| 
 
| 我这个程序是51(89c51)单片机通过fpga读写sram中fpga的接口模块的程序(verilog语言),问题是读写会出现错误,sram的时序我已注意检查了一次,仿真时序也是合理的,但是读写500个还是有70个左右的错误,所以希望大家帮忙看看。<br />硬件方面:共两块板子,系统板,fpga板(有sram_is61lc12816)之间的数据总线是直接相连的,读写,片选是分别通过一个电阻连接的(阻值记不清了,不知到会有影响么)。<br />软件思路:单片机给fpga四个数据,前两个是地址,后面的为要存储的数据或是读出的数据。这算一个过程。<br />//读写fpga内部ram模块,将51数据转换成对应的地址与存储数据模块,并将从sram来的数据送回51<br />//输入 en_sram_ns,使能信号mcu_wr_ns,mcu_rd_ns 51的读写信号,mcu_data 51的数据线<br /><br />//输出 en_consram2_ns ,sram_addr,sram_data,sram_wr_ns,sram_rd_ns<br /><br />//注意sram的读时序!!!!!!<br /><br />module com_sram2(sys_clk,en_sram_ns,mcu_wr_ns,mcu_rd_ns,mcu_data,<br />                en_consram2_ns,sram_addr,sram_data,sram_wr_ns,sram_rd_ns,sram_ub_ns,sram_lb_ns,wr_rd_nums);<br />        <br />input sys_clk,en_sram_ns,mcu_wr_ns,mcu_rd_ns;<br />inout[7:0] mcu_data;<br /><br />output en_consram2_ns,sram_wr_ns,sram_rd_ns,sram_ub_ns,sram_lb_ns;//sram的读写信号,和片选信号<br />output[3:0] wr_rd_nums;                                            //状态机方便调试<br />output[16:0] sram_addr;                                            //sram 的地址线<br /><br />inout[15:0] sram_data;<br /><br />reg[15:0] sram_data_out;<br />reg en_consram2_ns,sram_wr_ns,sram_rd_ns,sram_ub_ns,sram_lb_ns;<br />reg[16:0] sram_addr;<br /><br /><br />//中间变量<br />reg wr_rd,wr_rd_over;<br />reg[3:0] wr_rd_nums;<br />reg[7:0] mcu_data_temp,mcu_data_temp_m,mcu_data_temp_l;<br />reg[7:0] sram_addr_temp_m,sram_data_temp_m;<br />reg[15:0] sram_data_temp;<br /><br />parameter one=4'b0001,two=4'b0010,three=4'b0100,four=4'b1000;<br /><br />assign mcu_data=(!en_sram_ns&!mcu_rd_ns)?mcu_data_temp:8'bz;<br />assign sram_data=(!sram_wr_ns)?sram_data_temp:16'bz;<br /><br />always @(negedge en_sram_ns)<br />  begin<br />          case(wr_rd_nums)<br />                 one:begin<br />                        wr_rd_nums<=two;<br />                    end<br />                two:begin<br />                        wr_rd_nums<=three;<br />                     end<br />                three:begin<br />                        wr_rd_nums<=four;<br />                      end<br />                default:begin<br />                        wr_rd_nums<=one;<br />                     end<br />          endcase<br />  end<br /><br /><br />always @(posedge sys_clk)<br />  begin<br />     if(en_sram_ns)<br />       begin<br />        wr_rd<=1;                                //允许读写数据<br />        en_consram2_ns<=0;                        //使能sram<br />        sram_ub_ns<=0;                            <br />        sram_lb_ns<=0;                            //sram以字操作<br />        sram_wr_ns<=1;                            //关闭写<br />        sram_rd_ns<=1;                            //关闭读<br />        if(wr_rd_over)                        <br />          begin                                 //读写过程结束<br />             sram_addr<=11'bz;   <br />             wr_rd_over<=0;<br />          end<br />       end<br />     else<br />       begin<br />         sram_rd_ns<=0;                                //使能sram的读<br />         sram_wr_ns<=1;<br />         mcu_data_temp_m<=sram_data[15:8];<br />         mcu_data_temp_l<=sram_data[7:0];<br />        if((mcu_wr_ns^mcu_rd_ns)&wr_rd)<br />          begin<br />           case(wr_rd_nums)<br />               default:begin<br />                         sram_addr_temp_m<=mcu_data;<br />                        wr_rd<=0;                        //每次只读写一次,wr_rd作为标志记录是否读写过<br />                       end<br />                two:begin<br />                        sram_addr<={1'b0,sram_addr_temp_m,mcu_data};<br />                        wr_rd<=0;<br />                    end<br />                three:begin<br />                        if(!mcu_rd_ns)<br />                           mcu_data_temp<=mcu_data_temp_m;<br />                        else<br />                           sram_data_temp_m<=mcu_data;                //记录高位数据<br />                        wr_rd<=0;<br />                      end<br />                four:begin<br />                        if(!mcu_rd_ns)<br />                           mcu_data_temp<=mcu_data_temp_l;<br />                        else<br />                          begin<br />                            sram_data_temp<={sram_data_temp_m,mcu_data};<br />                            sram_wr_ns<=0;                                //使能sram的写<br />                          end<br />                        wr_rd<=0;<br />                        wr_rd_over<=1;<br />                      end<br />            endcase<br />          end<br />       end<br />  end<br /><br /><br />endmodule<br />     | 
 |