两个单口ram的乒乓操作,ISE联合modelsim仿真

首先导入两个单口ram的IP核,我设置的是写优先模式,同时设置了一个写使能信号

两个单口ram的乒乓操作,ISE联合modelsim仿真

首先设置状态机,第一个状态为闲置状态,第二个状态为写ram1,只把数据写进ram,不输出。第三个状态,写ram2读ram1,第四个状态为结束状态。自定义了一个信号为读使能信号,其实也不是读使能,就是决定输出是哪个ram的一个使能信号。读写的时候地址都要加1,所以定义了一个cnt信号作为状态转移。

接下来上代码:

module sing_ram2(
   input clka,
  input rst_n,
  input [7:0] din,
  output reg out_valid,
  output reg [7:0] dout,
  output wire [7:0] douta,
  output wire [7:0] doutb,
  output reg [1:0] state
    );

  reg [9:0] addra;
  reg [9:0] addrb;
  reg [9:0] cnt;
  
  reg we_wr1,we_wr2,en_rd1,en_rd2;
  parameter IDLE        =    2'b00;
  parameter RAM1_WR    =    2'b01;
  parameter RAM1_RD    =    2'b10;
  parameter RAM2_RD    =    2'b11;
 
always @(posedge clka or negedge rst_n)
       if(!rst_n)
         cnt<=0;
        else
          cnt<=cnt+1;
         
  always @(posedge clka or negedge rst_n)
       if(!rst_n)
         begin
           state<=IDLE;
         we_wr1<=1'b1;
           en_rd1<=1'b0;
           we_wr2<=1'b0;
           en_rd2<=1'b0;
         addra<=10'd0;
            addrb<=10'd0;
       end            
       else
           begin
              case(state)
                IDLE : if(we_wr1)    
                               state<=RAM1_WR;                        
                          else
                            state<=IDLE;
                RAM1_WR: if (we_wr1)
                                begin
                                  if(addra ==10'd1023)
                                 begin
                                    addra <= 10'd0; 
                                    state <= RAM1_RD;
                                end
                                else begin
                                    addra <= addra + 10'd1;
                                    state <= RAM1_WR;
                                    we_wr1<=1'b1;
                                 en_rd1<=1'b0;
                                 we_wr2<=1'b0;
                                 en_rd2<=1'b0;
                                    end
                                end
               RAM1_RD :
                            if(cnt ==10'd1023)
                                 begin
                                  // addrb <= 10'd0;
                                    state <= RAM2_RD;
                                end
                                else begin
                                    addrb <= addrb + 10'd1;
                                    addra <= addra + 10'd1;
                                    state <= RAM1_RD;
                                    we_wr1<=1'b0;
                                 en_rd1<=1'b1;
                                 we_wr2<=1'b1;
                                 en_rd2<=1'b0; 
                                    end
              RAM2_RD :     if(cnt==10'd1023)
                                begin
                                    //addra <= 10'd0;
                                    state <= RAM1_RD;
                                end
                                else begin
                                    addra <= addra + 10'd1;
                                    addrb <= addrb + 10'd1;
                                    state <= RAM2_RD;
                                     we_wr1<=1'b1;
                                  en_rd1<=1'b0;
                                  we_wr2<=1'b0;
                                  en_rd2<=1'b1;
                                    end
              endcase
            end

 always @(posedge clka or negedge rst_n)            
     begin
       if(!rst_n)
        begin
          dout<=0;
          out_valid<=0;
         end
        else if(en_rd1) 
          begin
            dout<=douta;
             out_valid<=1;
         end
        else if(en_rd2)
         begin 
            dout<=doutb;
             out_valid<=1;
            end
        else
          begin
            dout<=8'b0;
             out_valid<=0;
            end
     end

其实开始的时候也用一个双口ram试过,但是后来发现虽然双口ram的地址是a,b。但是它们是用同一个内存,所以写ram2的话就会把ram1的覆盖掉,不能进行同时读写的操作。