OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram)

最近在弄openrisc,之前有人在弄,并且写了一篇master thesis,我已经上传了:

http://download.csdn.net/detail/rill_zhen/5303401

下面的内容应该就是根据论文中的指导完成的,但是,不是我完成的,所以转载如下:

 

 

Ø  DE2-115和DE2-70的存储器配置

DE2-115相对于DE2-70在存储器方面有两处不同的地方就是:其一,SDRAM容量加倍了,但是DE2-115中的两片SDRAM(32Mx16),在硬件上直接连在一块了(像ADDR,WE,CAS,RAS这些信号两块SDRAM都是共用的),若用就只能把两块32Mx16的SDRAM连在一起当做128M的SDRAM来用;而DE2-70上两块SDRAM(好像各是16Mx16)则是分别控制的,既可以连起来用,也可以分别当做两个独立的SDRAM来用。之所以这样是为了节省信号线吧,但却给DE2-115板上的资源利用带来了很大的不便,比方说,我现在要用友晶的D5M视频采集模块来采集数据,搭建SOC系统,来验证我写的H.264视频编码器。D5M中的DE2-115的参考设计是把整块SDRAM(128M)都当做是视频流的buffer的,这样也忒浪费了吧,况且我如果再搭建SOC系统,移植操作系统的话还有什么资源可用呢(需要把编码生成的bitstream数据通过网口传送到PC机端验证),那便只能拼板,而查了一下两块DE2-115拼板用的HSMC排线,居然要3000多元钱。而DE2-70虽然sdram和fpga的容量不如DE2-115但却可以满足我的要求。其二,DE2-115的sram,又从DE2-70的32bit 2M同步SRAM(SSRAM),恢复到了DE2(DE2-35)时期的16位SRAM时代,我不是很懂,是SRAM的价格比SSRAM的价格要便宜吗,不过我知道现在的软核处理器(OR1200)都是32位的SRAM控制起来要比SSRAM麻烦得多,得在32bit和16bit之间反复转换。

Ø  Sram控制器的3中验证方案

本文设计了设计符合wishbone规范的SRAM控制器,用wishbone的总线功能模型BFM作了验证,在FPGA(DE2,DE2-115)上实现和验证,本文已给出了DE2-70上的wishbone总线规范的SSRAM控制器(用opencores的yadmc核来控制SSRAM,实在没有必要)。

OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram)_第1张图片

以DE2上的256K x 16 IS61LV25616为例来做研究吧,其实DE2-115上的SRAM也一样。需要用到IS61LV25616的model。

我觉得,Sram_wrapper的验证方案有以下3种,第一种直接用BFM和所写的sram_wrapper相连,读写数据,第二种用BFM作为master接口,sram_wrapper作为slave接口连接到wishbone总线上进行验证,第三种方案是对整个soc平台做系统验证。第二种是否没有必要?

Ø  DE2中sram控制器的时序要求

IS61LV25616的一些常用引脚的功能

OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram)_第2张图片

读和写时序按照参照datasheet中所介绍的这两种方式

OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram)_第3张图片

OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram)_第4张图片

在wishbone接口中需满足途中的基本时序要求。

IS61LV25616的verilog model在网络上很容易可以找到

View Code 
复制代码
  1 // IS61LV25616 Asynchronous SRAM, 256K x 16 = 4M; speed: 10ns.
  2 // Note; 1) Please include "+define+ OEb" in running script if you want to check
  3 //          timing in the case of OE_ being set.
  4 //       2) Please specify access time by defining tAC_10 or tAC_12.
  5 
  6 `define OEb
  7 `define tAC_10     //tAC_10 or tAC_12 defines different parameters
  8 `timescale 1ns/1ns
  9 
 10 module IS61LV25616 (A, IO, CE_, OE_, WE_, LB_, UB_);
 11 
 12 parameter dqbits =16;
 13 parameter memdepth =262143;
 14 parameter addbits =19;
 15 parameter Toha  =2;
 16 
 17 parameter Tsa   =2;
 18 
 19 `ifdef tAC_10         //if "`define tAC_10 " at beginning,sentences below are compiled
 20 parameter Taa   =10,
 21             Thzce =3,
 22           Thzwe =5;
 23 `endif
 24 
 25 `ifdef tAC_12        //if "`define tAC_12 " at beginning,sentences below are compiled
 26 parameter Taa   =12,
 27           Thzce =5,
 28           Thzwe =6;
 29 `endif
 30 
 31 input CE_, OE_, WE_, LB_, UB_;
 32 input [(addbits -1) : 0] A;
 33 inout [(dqbits -1) : 0] IO;
 34  
 35 wire [(dqbits -1) : 0] dout;
 36 reg  [(dqbits/2-1) : 0] bank0 [0 : memdepth]; 
 37 reg  [(dqbits/2-1) : 0] bank1 [0 : memdepth];
 38 //array to simulate SRAM
 39 // wire [(dqbits - 1) : 0] memprobe = {bank1[A], bank0[A]};
 40 
 41 wire r_en = WE_ & (~CE_) & (~OE_);   //WE=1,CE=OE=0 Read
 42 wire w_en = (~WE_) & (~CE_) & ((~LB_) | (~UB_)); //WE=CE=0,LB or UB="0",OE=x Write
 43 assign #(r_en ? Taa : Thzce) IO = r_en ? dout : 16'bz; 
 44 
 45 initial
 46   $timeformat (-9, 0.1, " ns", 10); //show current simulation time
 47 
 48 assign dout [(dqbits/2-1) : 0]        = LB_ ?8'bz : bank0[A];
 49 assign dout [(dqbits -1) : (dqbits/2)] = UB_ ?8'bz : bank1[A];
 50 
 51 always @(A or w_en)
 52 begin
 53     #Tsa    //address setup time
 54 if (w_en)
 55       #Thzwe
 56 begin
 57  bank0[A] = LB_ ? bank0[A] : IO [(dqbits/2-1) : 0];
 58  bank1[A] = UB_ ? bank1[A] : IO [(dqbits -1)   : (dqbits/2)];
 59 end
 60 end
 61  
 62 // Timing Check
 63 `ifdef tAC_10
 64 specify//sepcify delay
 65 specparam
 66       tSA   =0,
 67       tAW   =8,
 68       tSCE  =8,
 69       tSD   =6,
 70       tPWE2 =10,
 71       tPWE1 =8,
 72       tPBW  =8;
 73 `else
 74 
 75 `ifdef tAC_12
 76 specify
 77 specparam
 78       tSA   =0,
 79       tAW   =8,
 80       tSCE  =8,
 81       tSD   =6,
 82       tPWE2 =12,
 83       tPWE1 =8,
 84       tPBW  =8;
 85 `endif
 86 `endif
 87 
 88     $setup (A, negedge CE_, tSA);
 89     $setup (A, posedge CE_, tAW);
 90     $setup (IO, posedge CE_, tSD);
 91     $setup (A, negedge WE_, tSA);
 92     $setup (IO, posedge WE_, tSD);
 93     $setup (A, negedge LB_, tSA);
 94     $setup (A, negedge UB_, tSA);
 95 
 96     $width (negedge CE_, tSCE);
 97     $width (negedge LB_, tPBW);
 98     $width (negedge UB_, tPBW);
 99     `ifdef OEb
100     $width (negedge WE_, tPWE1);
101     `else
102     $width (negedge WE_, tPWE2);
103     `endif
104 
105 endspecify
106 
107 endmodule
复制代码

Ø  Sram控制器的设计

Sram_wrapper用状态机控制的,两个周期用于读写低16位,两个周期用于读写高16位,sram datasheet中的时序应该能满足,但是过于保守了,效率应该低了。

Sram_wrapper的源码

View Code 
复制代码
// Author(s):
// - Huailu Ren, [email protected]
//

// Revision 1.1  16:56 2011-4-28  hlren
// created
//

// synopsys translate_off
`include"timescale.v"
// synopsys translate_on

module sram_wrapper (
    wb_clk_i,
    wb_rst_i,

    wb_dat_i,
    //wb_dat_o,
    wb_adr_i,
    wb_sel_i,
    wb_we_i,
    wb_cyc_i,
    wb_stb_i,


    // Bi-Directional
    SRAM_DQ,

    // Outputs
    wb_dat_o,
    wb_ack_o,
    wb_err_o,
   
    SRAM_ADDR,
    SRAM_LB_N,
    SRAM_UB_N,
    SRAM_CE_N,
    SRAM_OE_N,
    SRAM_WE_N
);

//
// clock and reset signals
//
input         wb_clk_i;
  input         wb_rst_i;
//
// WB slave i/f
//
input  [31:0] wb_dat_i;
  output [31:0] wb_dat_o;
  input  [31:0] wb_adr_i;
  input  [ 3:0] wb_sel_i;
  input         wb_we_i;
  input         wb_cyc_i;
  input         wb_stb_i;
  output        wb_ack_o;
  output        wb_err_o;
//
// SRAM port
//
inout  [15:0]   SRAM_DQ;    // SRAM Data bus 16 Bits
output [17:0] SRAM_ADDR;    // SRAM Address bus 18 Bits
output        SRAM_LB_N;    // SRAM Low-byte Data Mask
output        SRAM_UB_N;    // SRAM High-byte Data Mask
output        SRAM_CE_N;    // SRAM Chip chipselect
output        SRAM_OE_N;    // SRAM Output chipselect
output        SRAM_WE_N;    // SRAM Write chipselect

  reg    [17:0] SRAM_ADDR;
  reg           SRAM_LB_N;
  reg           SRAM_UB_N;
  reg           SRAM_CE_N;
  reg           SRAM_OE_N;
  reg           SRAM_WE_N;
 
  reg [3:0] state, state_r;
  reg [15:0] wb_data_o_l, wb_data_o_u;
 
  reg [16:0] wb_addr_i_reg;
  reg [31:0] wb_data_i_reg;
  //reg [31:0] wb_data_o_reg;
reg [ 3:0] wb_sel_i_reg;
 
  reg ack_we, ack_re;
// *****************************************************************************
//  FSM
// *****************************************************************************
localparam IDLE =0;
  localparam WE0  =1;
  localparam WE1  =2;
  localparam WE2  =3;
  localparam WE3  =4;
  localparam RD0  =5;
  localparam RD1  =6;
  localparam RD2  =7;
  localparam RD3  =8;
  localparam ACK  =9;
 
  assign SRAM_DQ =  ( (state_r == WE0 || state_r == WE1) ? wb_data_i_reg[15: 0]
                    : (state_r == WE2 || state_r == WE3) ? wb_data_i_reg[31:16]
                    : 16'hzzzz);
assign wb_dat_o = {wb_data_o_u,wb_data_o_l};
 
  assign wb_ack_o = (state == ACK);
  assign wb_err_o = wb_cyc_i & wb_stb_i & (| wb_adr_i[23:19]);
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if(wb_rst_i)
      state <= IDLE;
    elsebegin
      case (state)
        IDLE : begin
          if (wb_cyc_i & wb_stb_i & wb_we_i &~ack_we)
            state <= WE0;
          elseif (wb_cyc_i & wb_stb_i &~wb_err_o &~wb_we_i &~ack_re)
            state <= RD0;
        end
        WE0 : state <= WE1;
        WE1 : state <= WE2;
        WE2 : state <= WE3;
        WE3 : state <= ACK;
        RD0 : state <= RD1;
        RD1 : state <= RD2;
        RD2 : state <= RD3;
        RD3 : state <= ACK;
        ACK : state <= IDLE;
        default : state <= IDLE;
      endcase
    end
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i)
      state_r <= IDLE;
    else
      state_r <= state;
  end
//
// Write acknowledge
//
always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i)
      ack_we <=1'b0;
else
    if (wb_cyc_i & wb_stb_i & wb_we_i &~ack_we)
      ack_we <= #11'b1;
else
      ack_we <= #11'b0;
end
 
//
// Read acknowledge
//
always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i)
      ack_re <=1'b0;
else
    if (wb_cyc_i & wb_stb_i &~wb_err_o &~wb_we_i &~ack_re)
      ack_re <= #11'b1;
else
      ack_re <= #11'b0;
end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      wb_addr_i_reg <=32'b0;
      wb_data_i_reg <=32'b0;
      wb_sel_i_reg  <=4'b0;
end
    else
    if (wb_cyc_i & wb_stb_i &~ack_re &~ack_we)
    begin
      wb_addr_i_reg <= wb_adr_i[18:2];
      wb_data_i_reg <= wb_dat_i[31:0];
      wb_sel_i_reg  <= wb_sel_i[3:0];
    end
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_ADDR <=18'b0;
end
    else
      case (state)
        WE0, WE1, RD0, RD1 :
          SRAM_ADDR <= {wb_addr_i_reg[16:0], 1'b0};
        WE2, WE3, RD2, RD3 :
          SRAM_ADDR <= {wb_addr_i_reg[16:0], 1'b1};
default : SRAM_ADDR <=18'hz;
endcase
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_LB_N <=1'b1;
end
    else
      case (state)
        WE0, WE1, RD0, RD1 :
          SRAM_LB_N <=~wb_sel_i[0];
        WE2, WE3, RD2, RD3 :
          SRAM_LB_N <=~wb_sel_i[2];
        default :
          SRAM_LB_N <=1'b1;
endcase
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_UB_N <=1'b1;
end
    else
      case (state)
        WE0, WE1, RD0, RD1 :
          SRAM_UB_N <=~wb_sel_i[1];
        WE2, WE3, RD2, RD3 :
          SRAM_UB_N <=~wb_sel_i[3];
        default :
          SRAM_UB_N <=1'b1;
endcase
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_CE_N <=1'b1;
end
    else
      case (state)
        WE0, WE1, RD0, RD1 :
          SRAM_CE_N <=1'b0;
        WE2, WE3, RD2, RD3 :
          SRAM_CE_N <=1'b0;
default :
          SRAM_CE_N <=1'b1;
endcase
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_OE_N <=1'b1;
end
    else
      case (state)
        RD0, RD1, RD2, RD3 :
          SRAM_OE_N <=1'b0;
default :
          SRAM_OE_N <=1'b1;
endcase
  end
 
  always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      SRAM_WE_N <=1'b1;
end
    else
      case (state)
        WE0, WE1, WE2, WE3 :
          SRAM_WE_N <=1'b0;
default :
          SRAM_WE_N <=1'b1;
endcase
  end
  //
  // assemble ouput data
  //
always @ (posedge wb_clk_i orposedge wb_rst_i) begin
    if (wb_rst_i) begin
      wb_data_o_l <=16'b0;
      wb_data_o_u <=16'b0;
end
    else
      case (state_r)
        RD0, RD1 :
          wb_data_o_l <= SRAM_DQ;
        RD2, RD3 :
          wb_data_o_u <= SRAM_DQ;
      endcase
  end
endmodule
复制代码

Ø  Sram_wrapper的wishbone BFM验证

Sram_wrapper的BFM验证的testbench代码如下:

View Code 
复制代码
  1 // Author(s):
  2 // - Huailu Ren, [email protected]
  3 //
  4 
  5 // Revision 1.1  17:45 2011-4-28  hlren
  6 // created
  7 //
  8 
  9 // synopsys translate_off
 10 `include"timescale.v"
 11 // synopsys translate_on
 12 
 13 module tb_sram_wrapper ;
 14 
 15 //
 16 // clock and reset signals
 17 //
 18 reg         wb_clk_i;
 19 reg         wb_rst_i;
 20 
 21 // *****************************************************************************
 22 //  wishbone master bus functional model
 23 // *****************************************************************************
 24 
 25 wire [31:0] wb_din_w;
 26 wire [31:0] wb_dout_w;
 27 wire [31:0] wb_adr_w;
 28 wire [ 3:0] wb_sel_w;
 29 wire        wb_we_w;
 30 wire        wb_cyc_w;
 31 wire        wb_stb_w;
 32 wire        wb_ack_w;
 33 wire        wb_err_w;
 34    
 35   wb_mast u_wb_mast(
 36     .clk  ( wb_clk_i ),
 37     .rst  ( wb_rst_i ),
 38    
 39     .adr  ( wb_adr_w ),
 40     .din  ( wb_din_w ),
 41     .dout ( wb_dout_w ),
 42     .cyc  ( wb_cyc_w ),
 43     .stb  ( wb_stb_w ),
 44     .sel  ( wb_sel_w ),
 45     .we   ( wb_we_w ),
 46     .ack  ( wb_ack_w ),
 47     .err  ( wb_err_w ),
 48     .rty  ( wb_rty_w )
 49   );
 50 
 51 // *****************************************************************************
 52 //  sram controller
 53 // *****************************************************************************
 54 
 55 wire [15:0]   SRAM_DQ_w;    // SRAM Data bus 16 Bits
 56 wire [17:0] SRAM_ADDR_w;    // SRAM Address bus 18 Bits
 57 wire        SRAM_LB_N_w;    // SRAM Low-byte Data Mask
 58 wire        SRAM_UB_N_w;    // SRAM High-byte Data Mask
 59 wire        SRAM_CE_N_w;    // SRAM Chip chipselect
 60 wire        SRAM_OE_N_w;    // SRAM Output chipselect
 61 wire        SRAM_WE_N_w;    // SRAM Write chipselect
 62 
 63  sram_wrapper DUT_sram_wrapper(
 64     .wb_clk_i  ( wb_clk_i ),
 65     .wb_rst_i  ( wb_rst_i ),
 66    
 67     .wb_dat_i  ( wb_dout_w ),
 68     .wb_dat_o  ( wb_din_w ),
 69     .wb_adr_i  ( wb_adr_w ),
 70     .wb_sel_i  ( wb_sel_w ),
 71     .wb_we_i   ( wb_we_w ),
 72     .wb_cyc_i  ( wb_cyc_w ),
 73     .wb_stb_i  ( wb_stb_w ),
 74     .wb_ack_o  ( wb_ack_w ),
 75     .wb_err_o  ( wb_err_w ),
 76 
 77 // SRAM
 78     .SRAM_DQ   ( SRAM_DQ_w ),
 79     .SRAM_ADDR ( SRAM_ADDR_w ),
 80     .SRAM_LB_N ( SRAM_LB_N_w ),
 81     .SRAM_UB_N ( SRAM_UB_N_w ),
 82     .SRAM_CE_N ( SRAM_CE_N_w ),
 83     .SRAM_OE_N ( SRAM_OE_N_w ),
 84     .SRAM_WE_N ( SRAM_WE_N_w )
 85 );
 86 
 87 // *****************************************************************************
 88 //  sram model
 89 // *****************************************************************************
 90 
 91   IS61LV25616 u_sram_model(
 92     .A   ( {1'b0,SRAM_ADDR_w[17:0]} ),
 93     .IO  ( SRAM_DQ_w ),
 94     .CE_ ( SRAM_CE_N_w ),
 95     .OE_ ( SRAM_OE_N_w ),
 96     .WE_ ( SRAM_WE_N_w ),
 97     .LB_ ( SRAM_LB_N_w ),
 98     .UB_ ( SRAM_UB_N_w )
 99   );
100 
101  
102 initialbegin
103     wb_clk_i <=0;
104     wb_rst_i <=0;
105 end
106  
107 always@(wb_clk_i)  begin
108          #10 wb_clk_i <=~wb_clk_i;
109 end
110 
111 reg [31:0] tmp_dat;
112 
113 reg [31:0] d0,d1,d2,d3;
114 
115 initialbegin
116 repeat (1) @ (posedge wb_clk_i);
117       wb_rst_i <=1;
118 repeat (3) @ (posedge wb_clk_i);
119       wb_rst_i <=0;
120 //write your test here!
121 repeat (1) @ (posedge wb_clk_i);
122       u_wb_mast.wb_wr1(32'h04,4'b1111,32'haabbccdd);
123       u_wb_mast.wb_rd1(32'h04,4'b1111,tmp_dat);
124       u_wb_mast.wb_wr1(32'h08,4'b1111,32'hddccbbaa);
125       u_wb_mast.wb_rd1(32'h08,4'b1111,tmp_dat);
126       $display($time,,"readfrom %x, value = %x\n",32'h00,tmp_dat);
127 //adr,adr+4,adr+8,adr+12
128       u_wb_mast.wb_wr4(32'h00,4'b1111,1,32'h01,32'h02,32'h03,32'h04);
129       u_wb_mast.wb_rd4(32'h00,4'b1111,3,d0,d1,d2,d3);
130       $display($time,,"read4from %x, value = %x , %x , %x , %x\n",32'h05,d0,d1,d2,d3);
131     #100
132       $finish;
133    
134 end
135  
136 initial
137 begin
138       $fsdbDumpfile("sram_wrapper.fsdb");
139       $fsdbDumpvars;
140 end
141 endmodule
复制代码

仿真结果

# INFO: WISHBONE MASTER MODEL INSTANTIATED (tb_sram_wrapper.u_wb_mast)
#
#                  571 readfrom 00000000, value = ddccbbaa
#
#                 1891 read4from 00000005, value = 00000001 , 00000002 , 00000003 , 00000004
#

没有错误

Ø  Sram_wrapper的soc系统仿真验证

加入sram_wrapper模块之后,并没有在sram空间上跑代码,只是对sram作了以下简单的读写实验,测试代码如下所示

View Code 
复制代码
 1 #include "orsocdef.h"
 2 #include "board.h"
 3 #include "uart.h"
 4 
 5 int
 6 main (void)
 7 {
 8 long gpio_in;
 9   REG32 (RGPIO_OE) =0xffffffff;
10 
11   uart_init();
12   
13   uart_print_str("2Hello World!\n");
14   
15 int i;
16 int t0, t1;
17   t0 =0xaabbccdd;
18 for(i=0;i<10;i++){
19 //REG32 (RGPIO_OUT) = t0;
20     REG32 (SRAM_BASE + i*4) = t0;
21     t1 = REG32 (SRAM_BASE + i*4);
22 //REG32 (RGPIO_OUT) = t1;
23 if(t0 == t1)
24       uart_print_str("correct!\n");
25 else
26       uart_print_str("error!\n");
27     t0 = t0 -0x01010101;
28   }
29   
30 while(1){
31     gpio_in = REG32 (RGPIO_IN);
32     gpio_in = gpio_in &0x0000ffff;
33     REG32 (RGPIO_OUT) = gpio_in;
34   }
35 
36 return0;
37 }
复制代码

仿真结果

# 2
# H
# e
# l
# l
# o

# W
# o
# r
# l
# d
# !
#
#
#
#
# c
# o
# r
# r
# e
# c
# t
# !
… …

在fpga上的验证几个月前跑过,没有留图,结果与设想的一致,是没有错误的。

Ø  Ssram控制器的设计与验证

Ssram控制器的设计与验证,与sram相似,只不过它是同步的,ssram的model自己写即可,而且它是32位的,控制起来就简单多了。

关于DE2-70上的ssram控制器,参考设计orpXL中用yadmc核来控制ssram,是没有必要的。Ssram的控制代码如下

View Code 
复制代码
  1 //----------------------------------------------------------------------------//
  2 // Filename       : ssram_wrapper.v                                        //
  3 // Author         : Huailu Ren ...()                                       //
  4 // Email          : [email protected]                                       //
  5 // Created        : 23:54 2011/5/17                                           //
  6 //----------------------------------------------------------------------------//
  7 // Description    :                                                           //
  8 ////
  9 // $Id$                                                                       //
 10 //----------------------------------------------------------------------------//
 11 
 12 module ssram_wrapper(
 13 input              clk_i,
 14 input              rst_i,
 15    
 16 input              wb_stb_i,
 17 input              wb_cyc_i,
 18 outputreg         wb_ack_o,
 19 input      [31: 0] wb_addr_i,
 20 input      [ 3: 0] wb_sel_i,
 21 input              wb_we_i,
 22 input      [31: 0] wb_data_i,
 23 output     [31: 0] wb_data_o,
 24 // SSRAM side
 25 inout      [31: 0] SRAM_DQ,     //  SRAM Data Bus 32 Bits
 26 inout      [ 3: 0] SRAM_DPA,    //  SRAM Parity Data Bus
 27 // Outputs                     
 28 output             SRAM_CLK,    //  SRAM Clock
 29 output     [18: 0] SRAM_A,      //  SRAM Address bus 21 Bits
 30 output             SRAM_ADSC_N, //  SRAM Controller Address Status  
 31 output             SRAM_ADSP_N, //  SRAM Processor Address Status
 32 output             SRAM_ADV_N,  //  SRAM Burst Address Advance
 33 output     [ 3: 0] SRAM_BE_N,   //  SRAM Byte Write Enable
 34 output             SRAM_CE1_N,  //  SRAM Chip Enable
 35 output             SRAM_CE2,    //  SRAM Chip Enable
 36 output             SRAM_CE3_N,  //  SRAM Chip Enable
 37 output             SRAM_GW_N,   //  SRAM Global Write Enable
 38 output             SRAM_OE_N,   //  SRAM Output Enable
 39 output             SRAM_WE_N    //  SRAM Write Enable
 40   );
 41 
 42 // request signal
 43 wire request;
 44  
 45 // request signal's rising edge
 46 reg  request_delay;
 47 wire request_rising_edge;
 48 wire is_read, is_write;
 49 
 50 // ack signal
 51 reg  ram_ack;
 52  
 53 // get request signal
 54 assign request = wb_stb_i & wb_cyc_i;
 55  
 56 // Internal Assignments
 57 assign is_read  = wb_stb_i & wb_cyc_i &~wb_we_i;
 58 assign is_write = wb_stb_i & wb_cyc_i & wb_we_i;
 59  
 60 // Output Assignments
 61 assign wb_data_o      = SRAM_DQ;
 62 
 63 assign SRAM_DQ[31:24] = (wb_sel_i[3] & is_write) ? wb_data_i[31:24] : 8'hzz;
 64 assign SRAM_DQ[23:16] = (wb_sel_i[2] & is_write) ? wb_data_i[23:16] : 8'hzz;
 65 assign SRAM_DQ[15: 8] = (wb_sel_i[1] & is_write) ? wb_data_i[15: 8] : 8'hzz;
 66 assign SRAM_DQ[ 7: 0] = (wb_sel_i[0] & is_write) ? wb_data_i[ 7: 0] : 8'hzz;
 67 
 68 assign SRAM_DPA     =4'hz;
 69 
 70 assign SRAM_CLK     = clk_i;
 71 assign SRAM_A       = wb_addr_i[20:2];
 72 assign SRAM_ADSC_N  =~(is_write);
 73 assign SRAM_ADSP_N  =~(is_read);
 74 assign SRAM_ADV_N   =1'b1;
 75 assign SRAM_BE_N[3] =~(wb_sel_i[3] & request);
 76 assign SRAM_BE_N[2] =~(wb_sel_i[2] & request);
 77 assign SRAM_BE_N[1] =~(wb_sel_i[1] & request);
 78 assign SRAM_BE_N[0] =~(wb_sel_i[0] & request);
 79 assign SRAM_CE1_N   =~request;
 80 assign SRAM_CE2     =1'b1;
 81 assign SRAM_CE3_N   =1'b0;
 82 assign SRAM_GW_N    =1'b1;
 83 assign SRAM_OE_N    =~is_read;
 84 assign SRAM_WE_N    =~is_write;
 85  
 86 // get the rising edge of request signal
 87 always @ (posedge clk_i)
 88 begin
 89 if(rst_i ==1)
 90       request_delay <=0;
 91 else
 92       request_delay <= request;
 93 end
 94  
 95 assign request_rising_edge = (request_delay ^ request) & request;
 96 
 97 // generate a 1 cycle acknowledgement for each request rising edge
 98 always @ (posedge clk_i)
 99 begin
100 if (rst_i ==1)
101       ram_ack <=0;
102 elseif (request_rising_edge ==1)
103       ram_ack <=1;
104 else
105       ram_ack <=0;
106 end
107 
108 // register wb_ack output, because onchip ram0 uses registered output
109 always @ (posedge clk_i)
110 begin
111 if (rst_i ==1)
112       wb_ack_o <=0;
113 else
114       wb_ack_o <= ram_ack;
115 end
116 
117 endmodule
复制代码

并没有写testbench,直接在fpga上跑了,而且是跑的程序。经验证没有问题。

源码可以在这里下载

  • 稍后。。。

To Do

  • 用所写的sram_wrapper基于DE2平台让or1200在sram空间跑下代码
  • 修改以下用所写的sram_wrapper移植到DE2-115平台上

To Do--关于opencore,or1200的soc平台

  • OR1200的引导方案设计(基于硬件或者软件uart控制)
  • 移植uc/os II操作系统
  • 驱动起来DE2-70上的网卡
  • 加入jtag模块
  • 移植u-boot
  • 移植ucLinux
  • ……

See Also

(原创)基于or1200最小sopc系统搭建(三)--串口
(原创)基于or1200最小sopc系统搭建(二)--QuartuII工程及DE2平台下载
(原创)基于or1200最小sopc系统搭建(一)--搭建及仿真(DE2,DE2-70)
(原创)构建基于aemb的sopc系统(五)--系统仿真与fpga验证(DE2-70平台)

你可能感兴趣的:(OpenRisc-10-基于or1200最小sopc系统搭建(四)--(sram,ssram))