赞
踩
user输入: valid信号 , 要输出的值
输出 :一个周期读valid , 读到的值
module spi_drive#( parameter P_DATA_WIDTH = 8 , P_READ_DATA_WIDTH = 8 , P_CPOL = 0 , P_CPHL = 0 )( input i_clk , input i_rst , output o_spi_clk , output o_spi_cs , output o_spi_mosi , input i_spi_miso , input [P_DATA_WIDTH - 1 :0] i_user_data , input i_user_valid , output o_user_ready , output [P_READ_DATA_WIDTH - 1:0] o_user_read_data , output o_user_read_valid ); reg ro_spi_clk ; reg ro_spi_cs ; reg ro_spi_mosi ; reg ro_user_ready ; reg [P_DATA_WIDTH - 1:0] r_user_data ; reg r_run ; reg [15:0] r_cnt ; reg r_spi_cnt ; reg [P_READ_DATA_WIDTH - 1:0] ro_user_read_data ; reg ro_user_read_valid ; reg r_run_1d ; /***************wire******************/ wire w_user_active ; wire w_run_negedge ; /***************assign****************/ assign o_spi_clk = ro_spi_clk ; assign o_spi_cs = ro_spi_cs ; assign o_spi_mosi = ro_spi_mosi ; assign o_user_ready = ro_user_ready ; assign o_user_read_data = ro_user_read_data ; assign o_user_read_valid = ro_user_read_valid ; assign w_run_negedge = !r_run & r_run_1d ; /***************always****************/ assign w_user_active = i_user_valid & o_user_ready; always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_ready <='d1; else if(w_user_active) ro_user_ready <= 'd0; else if(w_run_negedge) ro_user_ready <= 'd1; else ro_user_ready <= ro_user_ready; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_user_data <= 'd0; else if(w_user_active) r_user_data <= i_user_data; else if(r_spi_cnt) r_user_data <= r_user_data << 1; else r_user_data <= r_user_data; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_run <= 'd0; else if(r_spi_cnt && r_cnt == 7) r_run <= 'd0; else if(w_user_active) r_run <= 'd1; else r_run <= r_run; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_run_1d <= 'd0; else r_run_1d <= r_run; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_cnt <= 'd0; else if(r_spi_cnt && r_cnt == 7) r_cnt <= 'd0; else if(r_spi_cnt) r_cnt <= r_cnt + 1; else r_cnt <= r_cnt; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_spi_cnt <= 'd0; else if(r_run) r_spi_cnt <= r_spi_cnt + 1; else r_spi_cnt <= 'd0; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_clk <= P_CPOL; else if(r_run) ro_spi_clk <= ~ro_spi_clk; else ro_spi_clk <= P_CPOL; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_cs <= 'd1; else if(w_user_active) ro_spi_cs <= 'd0; else if(!r_run) ro_spi_cs <= 'd1; else ro_spi_cs <= ro_spi_cs; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_mosi <= 'd0; else if(w_user_active) ro_spi_mosi <= i_user_data[P_DATA_WIDTH - 1]; else if(r_spi_cnt) ro_spi_mosi <= r_user_data[P_DATA_WIDTH - 2]; else ro_spi_mosi <= ro_spi_mosi; end always@(posedge ro_spi_clk,posedge i_rst) begin if(i_rst) ro_user_read_data <= 'd0; else ro_user_read_data <= {ro_user_read_data[P_DATA_WIDTH - 2 : 0],i_spi_miso}; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_read_valid <= 'd0; else if(r_spi_cnt && r_cnt == 7) ro_user_read_valid <= 'd1; else ro_user_read_valid <= 'd0; end endmodule
实际上就是加入了(芯片命令cmd + 寄存器地址) 的数据。读写操作的位数可以由spi控制器来控制,用于完成各种spi协议芯片的读写任务。
读数据
写数据
module spi_drive#( parameter P_DATA_WIDTH = 8 , P_OP_LEN = 32, P_READ_DATA_WIDTH = 8 , P_CPOL = 0 , P_CPHL = 0 )( input i_clk ,//系统时钟 input i_rst ,//复位 //spi驱动 output o_spi_clk ,//spi的clk output o_spi_cs ,//spi的片选 output o_spi_mosi ,//spi的主机输出 input i_spi_miso ,//spi的从机输入 //操作通道 input [P_OP_LEN - 1 :0] i_user_op_data ,//操作数据(命令8bit+地址24bit) input [1 :0] i_user_op_type ,//操作类型(读、写、指令) input [15:0] i_user_op_len ,//操作数据的长 32 或 8 input [15:0] i_user_clk_len ,//时钟周期 //握手信号 input i_user_op_valid ,//用户的有效信号 output o_user_op_ready ,//用户的准备信号 //与上层交互通道 input [P_DATA_WIDTH - 1 :0] i_user_write_data ,//写的数据 output o_user_write_req ,//写数据请求 //输出结果通道 output [P_READ_DATA_WIDTH - 1:0] o_user_read_data ,//读到的数据 output o_user_read_valid //读数据有效 ); //3个状态: 命令/读/写 /***************parameter*************/ localparam P_OP_TYPE_INS = 0, P_OP_READ = 1, P_OP_WRITE = 2; /***************reg*******************/ reg ro_spi_clk ; reg ro_spi_cs ; reg ro_spi_mosi ; reg ro_user_ready ; reg [P_OP_LEN - 1:0] r_user_op_data ; reg [1 :0] r_user_op_type ; reg [15:0] r_user_op_len ; reg [15:0] r_user_clk_len ; reg [P_DATA_WIDTH - 1:0] r_user_data ; reg r_run ; reg [15:0] r_cnt ; reg r_spi_cnt ; reg [P_READ_DATA_WIDTH - 1:0] ro_user_read_data ; reg ro_user_read_valid ; reg r_run_1d ; reg ro_user_write_req ; reg ro_user_write_req_1d; reg [15:0] r_write_cnt ; reg [P_DATA_WIDTH - 1 :0] r_user_write_data ; reg [15:0] r_read_cnt ; /***************wire******************/ wire w_user_active ; wire w_run_negedge ; /***************component*************/ /***************assign****************/ assign o_spi_clk = ro_spi_clk ; assign o_spi_cs = ro_spi_cs ; assign o_spi_mosi = ro_spi_mosi ; assign o_user_op_ready = ro_user_ready ; assign o_user_read_data = ro_user_read_data ; assign o_user_read_valid = ro_user_read_valid ; assign w_run_negedge = !r_run & r_run_1d ; assign o_user_write_req = ro_user_write_req ; /***************always****************/ assign w_user_active = i_user_op_valid & o_user_op_ready; //控制准备信号 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_ready <='d1; else if(w_user_active) ro_user_ready <= 'd0; else if(w_run_negedge) ro_user_ready <= 'd1; else ro_user_ready <= ro_user_ready; end //操作总线,锁存USER的数据指令 always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin r_user_op_type <= 'd0; r_user_op_len <= 'd0; r_user_clk_len <= 'd0; end else if(w_user_active) begin r_user_op_type <= i_user_op_type; r_user_op_len <= i_user_op_len ; r_user_clk_len <= i_user_clk_len; end else begin r_user_op_type <= r_user_op_type; r_user_op_len <= r_user_op_len ; r_user_clk_len <= r_user_clk_len; end end //激活后, 锁存操作数据 //下降沿, spi数据并转串 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_user_op_data <= 'd0; else if(w_user_active) r_user_op_data <= i_user_op_data;//指令8bit + 24bit地址 else if(r_spi_cnt)//spi输出时,并转 r_user_op_data <= r_user_op_data << 1; else r_user_op_data <= r_user_op_data; end //run总线运行标志 //下降沿+spi的clk周期到达指定值 ,停止 //激活后,运行 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_run <= 'd0; else if(r_spi_cnt && r_cnt == r_user_clk_len - 1) r_run <= 'd0; else if(w_user_active) r_run <= 'd1; else r_run <= r_run; end // run 打拍 获得下降沿 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_run_1d <= 'd0; else r_run_1d <= r_run; end //spi时钟周期计数 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_cnt <= 'd0; else if(r_spi_cnt && r_cnt == r_user_clk_len - 1) r_cnt <= 'd0; else if(r_spi_cnt) r_cnt <= r_cnt + 1; else r_cnt <= r_cnt; end //spi时钟计数,用于判断上升/下降沿 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_spi_cnt <= 'd0; else if(r_run) r_spi_cnt <= r_spi_cnt + 1; else r_spi_cnt <= 'd0; end //spi时钟信号,run就开始翻转 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_clk <= P_CPOL; else if(r_run) ro_spi_clk <= ~ro_spi_clk; else ro_spi_clk <= P_CPOL; end //spi片选信号 ,激活就片选 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_cs <= 'd1; else if(w_user_active) ro_spi_cs <= 'd0; else if(!r_run) ro_spi_cs <= 'd1; else ro_spi_cs <= ro_spi_cs; end //spi输出引脚 //1. 输出操作数据 //2. 输出要写出去的数据 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_spi_mosi <= 'd0; else if(w_user_active)//输出操作数据 最高位 指令+地址 ro_spi_mosi <= i_user_op_data[P_OP_LEN - 1];//operation else if(r_spi_cnt && r_cnt < r_user_op_len - 1)//依次输出操作数据次高位 ro_spi_mosi <= r_user_op_data[P_OP_LEN - 2]; else if(r_user_op_type == P_OP_WRITE && r_spi_cnt)//串行输出写数据 ro_spi_mosi <= r_user_write_data[7]; else ro_spi_mosi <= ro_spi_mosi; end // //2.(上升沿 + 周期计数器到P_OP_LEN -2 ||写数据计数==15 ) && 写状态 // 因为r_cnt是基于spi_clk(系统时钟/2)来计数的,!r_spi_cnt是作为i_clk时钟位置的判断 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_write_req <= 'd0; else if(r_cnt >= r_user_clk_len - 5) ro_user_write_req <= 'd0; else if(((!r_spi_cnt && r_cnt == P_OP_LEN-2) || r_write_cnt == 15) && r_user_op_type == P_OP_WRITE ) ro_user_write_req <= 'd1; else ro_user_write_req <= 'd0; end // 获得延时1个周期的写请求信号 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_write_req_1d <= 'd0; else ro_user_write_req_1d <= ro_user_write_req; end // 1.用延时一个周期的写请求信号(此时外部数据已经更新),来锁存输入的要写的数据 // 2.spi_clk的下降沿 位移数据 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_user_write_data <= 'd0; else if(ro_user_write_req_1d) r_user_write_data <= i_user_write_data; else if(r_spi_cnt) r_user_write_data <= r_user_write_data << 1; else r_user_write_data <= r_user_write_data; end //写请求后 r_write_cnt 写计数 0 ~ 15 用于下次产生写请求 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_write_cnt <= 'd0; else if(r_write_cnt == 15 || ro_spi_cs) r_write_cnt <= 'd0; else if(ro_user_write_req || r_write_cnt) r_write_cnt <= r_write_cnt + 1; else r_write_cnt <= r_write_cnt; end /*--------------------------读---------------------------------*/ //完成命令+地址的指令后,读数据 always@(posedge ro_spi_clk,posedge i_rst) begin if(i_rst) ro_user_read_data <= 'd0; else if(r_cnt >= r_user_op_len ) ro_user_read_data <= {ro_user_read_data[P_READ_DATA_WIDTH - 2 : 0],i_spi_miso}; else ro_user_read_data <= ro_user_read_data; end // 完成了命令+地址的指令后,读计数 0 ~ 8 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_read_cnt <= 'd0; else if(r_read_cnt == P_READ_DATA_WIDTH || ro_spi_cs) r_read_cnt <= 'd0; else if(r_spi_cnt && r_cnt >= r_user_op_len - 0 && r_user_op_type == P_OP_READ) r_read_cnt <= r_read_cnt + 1; else r_read_cnt <= r_read_cnt; end //读数据有效信号 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_user_read_valid <= 'd0; else if(r_spi_cnt && r_read_cnt == P_READ_DATA_WIDTH - 1 && r_user_op_type == P_OP_READ) ro_user_read_valid <= 'd1; else ro_user_read_valid <= 'd0; end endmodule
连续读出存在FIFO中的数据
module flash_ctrl#( parameter P_DATA_WIDTH = 8 ,//数据位宽 P_OP_LEN = 32,//指令长度 P_READ_DATA_WIDTH = 8 ,//读数据位宽 P_CPOL = 0 ,//空闲时时钟状态 P_CPHL = 0 //采集数据时钟沿 )( input i_clk ,//用户时钟 input i_rst ,//用户复位 /*--------用户接口--------*/ input [1 :0] i_operation_type ,//操作类型 input [23:0] i_operation_addr ,//操作地址 input [8 :0] i_operation_num ,//限制用户每次最多写256字节 input i_operation_valid ,//操作握手有效 output o_operation_ready ,//操作握手准备 input [P_DATA_WIDTH - 1 :0] i_write_data ,//写数据 input i_write_sop ,//写数据-开始信号 input i_write_eop ,//写数据-结束信号 input i_write_valid ,//写数据-有效信号 output [P_DATA_WIDTH - 1 :0] o_read_data ,//读数据 output o_read_sop ,//读数据-开始信号 output o_read_eop ,//读数据-结束信号 output o_read_valid ,//读数据-有效信号 /*--------驱动接口--------*/ output [P_OP_LEN - 1 :0] o_user_op_data ,//操作数据(指令8bit+地址24bit) output [1 :0] o_user_op_type ,//操作类型(读、写、指令) output [15:0] o_user_op_len ,//操作数据的长度32、8 output [15:0] o_user_clk_len ,//时钟周期 output o_user_op_valid ,//用户的有效信号 input i_user_op_ready ,//用户的准备信号 output [P_DATA_WIDTH - 1 :0] o_user_write_data ,//写数据 input i_user_write_req ,//写数据请求 input [P_READ_DATA_WIDTH - 1:0] i_user_read_data ,//读数据 input i_user_read_valid //读数据有效 ); /***************function**************/ /***************parameter*************/ //用户接口操作类型 localparam P_TYPE_CLEAR = 0 , P_TYPE_WRITE = 1 , P_TYPE_READ = 2 ; //SPI总线驱动器操作类型 localparam P_OP_TYPE_INS = 0, P_OP_READ = 1, P_OP_WRITE = 2; //状态机状态 localparam P_IDLE = 0 , P_RUN = 1 , P_W_EN = 2 , P_W_INS = 3 , P_W_DATA = 4 , P_R_INS = 5 , P_R_DATA = 6 , P_CLEAR = 7 , P_BUSY = 8 , P_BUSY_CHECK = 9 , P_BUSY_WAIT = 10 ; /***************port******************/ /***************mechine***************/ //状态机 reg [7 :0] r_st_current ; reg [7 :0] r_st_next ; reg [7 :0] r_st_cnt ; /***************reg*******************/ reg [1 :0] ri_operation_type ; reg [23:0] ri_operation_addr ; reg [8 :0] ri_operation_num ; reg [P_DATA_WIDTH - 1 :0] ri_write_data ; reg ri_write_sop ; reg ri_write_eop ; reg ri_write_valid ; reg r_user_ready_1d ; reg [P_OP_LEN - 1 :0] ro_user_op_data ; reg [1 :0] ro_user_op_type ; reg [15:0] ro_user_op_len ; reg [15:0] ro_user_clk_len ; reg ro_user_op_valid ; reg [P_DATA_WIDTH - 1 :0] ri_user_read_data ; reg ri_user_read_valid ; reg ro_operation_ready ; reg [7 :0] ro_read_data ; reg ro_read_sop ; reg ro_read_eop ; reg ro_read_valid ; reg r_fifo_read_rden ; reg r_fifo_read_rden_1d ; reg r_fifo_read_pos ; reg r_fifo_read_emp_1d ; reg r_fifo_read_wren ; /***************wire******************/ wire w_operation_active ; wire w_user_ready_pos ; wire w_spi_drive_act ; wire w_fifo_read_empty ; wire [7 :0] w_read_data ; /***************component*************/ //输入:用户写入想要 写进外设的数据 //输出:spi请求数据的时候,输出要写的数据 FLASH_CTRL_FIFO_DATA FLASH_CTRL_FIFO_DATA_U0 ( .clk (i_clk ), .srst (i_rst ), .din (ri_write_data ), .wr_en (ri_write_valid ), .rd_en (i_user_write_req ), .dout (o_user_write_data ), .full (), .empty () ); //输入:spi读到的数据,写进去 //输出:用户要读取数据的时候,输出 FLASH_CTRL_FIFO_DATA FLASH_CTRL_FIFO_DATA_READ_U0 ( .clk (i_clk ), .srst (i_rst ), .din (ri_user_read_data ), .wr_en (r_fifo_read_wren ), .rd_en (r_fifo_read_rden ), .dout (w_read_data ), .full (), .empty (w_fifo_read_empty ) ); /***************assign****************/ assign w_operation_active = i_operation_valid & o_operation_ready ; assign w_user_ready_pos = r_user_ready_1d & i_user_op_ready ; assign o_user_op_data = ro_user_op_data ; assign o_user_op_type = ro_user_op_type ; assign o_user_op_len = ro_user_op_len ; assign o_user_clk_len = ro_user_clk_len ; assign o_user_op_valid = ro_user_op_valid ; assign o_operation_ready = ro_operation_ready ; assign w_spi_drive_act = o_user_op_valid & i_user_op_ready ; // assign o_read_data = ro_read_data ; assign o_read_sop = ro_read_sop ; assign o_read_eop = ro_read_eop ; assign o_read_valid = ro_read_valid ; assign o_read_data = ro_read_data ; /***************always****************/ //状态机跳转 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_st_current <= P_IDLE; else r_st_current <= r_st_next; end //跳转条件 always@(*) begin case(r_st_current) P_IDLE : r_st_next = w_operation_active ? P_RUN : P_IDLE ; //空闲状态,用户激活时跳转 P_RUN : r_st_next = ri_operation_type == P_TYPE_READ ? P_R_INS : P_W_EN ; //开始运行状态机,读/写 P_W_EN : r_st_next = w_spi_drive_act ? ri_operation_type == P_TYPE_WRITE ? P_W_INS : P_CLEAR //判断是写数据还是擦除 : P_W_EN ;//写使能状态 P_W_INS : r_st_next = w_spi_drive_act ? P_W_DATA : P_W_INS ; //写数据指令状态 P_W_DATA : r_st_next = i_user_op_ready ? P_BUSY : P_W_DATA ; //写数据 P_R_INS : r_st_next = w_spi_drive_act ? P_R_DATA : P_R_INS ; //读数据指令状态 P_R_DATA : r_st_next = i_user_op_ready ? P_BUSY : P_R_DATA ; //读数据 P_CLEAR : r_st_next = w_spi_drive_act ? P_BUSY : P_CLEAR ; P_BUSY : r_st_next = w_spi_drive_act ? P_BUSY_CHECK : P_BUSY ; //读状态寄存器 P_BUSY_CHECK : r_st_next = ri_user_read_valid ? i_user_read_data[0] ? P_BUSY_WAIT : P_IDLE : P_BUSY_CHECK ; //根据返回的状态值,判断是否繁忙 P_BUSY_WAIT : r_st_next = r_st_cnt == 255 ? P_BUSY : P_BUSY_WAIT ; //等待255个周期,重启读忙 default : r_st_next = P_W_EN; endcase end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_st_cnt <= 'd0; else if(r_st_current != r_st_next) r_st_cnt <= 'd0; else r_st_cnt <= r_st_cnt + 1; end /*--------驱动逻辑--------*/ //第三段状态机 always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ro_user_op_data <= 'd0; ro_user_op_type <= 'd0; ro_user_op_len <= 'd0; ro_user_clk_len <= 'd0; ro_user_op_valid <= 'd0; end else if(r_st_current == P_W_EN) begin //发送写使能指令 ro_user_op_data <= {8'h06,8'h00,8'h00,8'h00}; ro_user_op_type <= P_OP_TYPE_INS; ro_user_op_len <= 8; ro_user_clk_len <= 8; ro_user_op_valid <= 'd1; end else if(r_st_current == P_W_INS) begin //发送写数据指令 ro_user_op_data <= {8'h02,ri_operation_addr}; ro_user_op_type <= P_OP_WRITE; ro_user_op_len <= 32; ro_user_clk_len <= 32 + 8 * ri_operation_num; ro_user_op_valid <= 'd1; end else if(r_st_current == P_R_INS) begin //发送读数据指令 ro_user_op_data <= {8'h03,ri_operation_addr}; ro_user_op_type <= P_OP_READ; ro_user_op_len <= 32; ro_user_clk_len <= 32 + 8 * ri_operation_num; ro_user_op_valid <= 'd1; end else if(r_st_current == P_CLEAR) begin //发送擦除指令 ro_user_op_data <= {8'h20,ri_operation_addr}; ro_user_op_type <= P_OP_TYPE_INS; ro_user_op_len <= 32; ro_user_clk_len <= 32; ro_user_op_valid <= 'd1; end else if(r_st_current == P_BUSY) begin //发送读状态-BUSY ro_user_op_data <= {8'h05,24'd0}; ro_user_op_type <= P_OP_READ; ro_user_op_len <= 8; ro_user_clk_len <= 16; ro_user_op_valid <= 'd1; end else begin ro_user_op_data <= ro_user_op_data; ro_user_op_type <= ro_user_op_type; ro_user_op_len <= ro_user_op_len ; ro_user_clk_len <= ro_user_clk_len; ro_user_op_valid <= 'd0; end end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_user_ready_1d <= 'd0; else r_user_ready_1d <= i_user_op_ready; end // 锁存读到的数据和有效信号 always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ri_user_read_data <= 'd0; ri_user_read_valid <= 'd0; end else begin ri_user_read_data <= i_user_read_data ; ri_user_read_valid <= i_user_read_valid ; end end /*--------用户逻辑--------*/ //握手激活,开始操作 always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ri_operation_type <= 'd0; ri_operation_addr <= 'd0; ri_operation_num <= 'd0; end else if(w_operation_active) begin ri_operation_type <= i_operation_type; ri_operation_addr <= i_operation_addr; ri_operation_num <= i_operation_num ; end else begin ri_operation_type <= ri_operation_type; ri_operation_addr <= ri_operation_addr; ri_operation_num <= ri_operation_num ; end end //激活拉低准备信号 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_operation_ready <= 'd1; else if(r_st_next == P_IDLE) ro_operation_ready <= 'd1; else if(w_operation_active) ro_operation_ready <= 'd0; else ro_operation_ready <= ro_operation_ready; end //*------------------用户写入数据存入FIFO ------------------------*/ always@(posedge i_clk,posedge i_rst) begin if(i_rst) begin ri_write_data <= 'd0; ri_write_sop <= 'd0; ri_write_eop <= 'd0; ri_write_valid <= 'd0; end else begin ri_write_data <= i_write_data ; ri_write_sop <= i_write_sop ; ri_write_eop <= i_write_eop ; ri_write_valid <= i_write_valid; end end /*-----------------------从FIFO中读数据---------------------------------*/ //从FIFO中读数据使能开启 always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_read_rden <= 'd0; else if(w_fifo_read_empty) r_fifo_read_rden <= 'd0; else if(r_st_current == P_R_DATA && r_st_next != P_R_DATA) r_fifo_read_rden <= 'd1; else r_fifo_read_rden <= r_fifo_read_rden; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_read_rden_1d <= 'd0; else r_fifo_read_rden_1d <= r_fifo_read_rden; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_read_pos <= 'd0; else r_fifo_read_pos <= !r_fifo_read_rden_1d && r_fifo_read_rden; end always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_read_emp_1d <= 'd0; else r_fifo_read_emp_1d <= w_fifo_read_empty; end //开始fifo数据输出 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_read_sop <= 'd0; else if(r_fifo_read_pos) ro_read_sop <= 'd1; else ro_read_sop <= 'd0; end //结束fifo数据输出 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_read_eop <= 'd0; else if(w_fifo_read_empty && !r_fifo_read_emp_1d && ro_read_valid) ro_read_eop <= 'd1; else ro_read_eop <= 'd0; end //fifo读有效信号指示 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_read_valid <= 'd0; else if(ro_read_eop) ro_read_valid <= 'd0; else if(r_fifo_read_pos) ro_read_valid <= 'd1; else ro_read_valid <= ro_read_valid; end //从FIFO中读出的数据 always@(posedge i_clk,posedge i_rst) begin if(i_rst) ro_read_data <= 'd0; else ro_read_data <= w_read_data; end //---------------------------将读到的数据写入FIFO------------------------------*/ always@(posedge i_clk,posedge i_rst) begin if(i_rst) r_fifo_read_wren <= 'd0; else if(r_st_current == P_R_DATA) r_fifo_read_wren <= i_user_read_valid; else r_fifo_read_wren <= 'd0; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。