(原创)基于or1200最小sopc系统搭建(四)--(sram,ssram)(DE2,DE2-70, DE2-115)
打算以后继续进行基于opencore的SOC的学习,写些关于openrisc,opencores的文章。这段时间有种感悟,怎样避免“再发明相同的车轮”呢,写博客是个好方法,利人利己。
Ø 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,实在没有必要)。
以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的一些常用引脚的功能
读和写时序按照参照datasheet中所介绍的这两种方式
在wishbone接口中需满足途中的基本时序要求。
IS61LV25616的verilog model在网络上很容易可以找到
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的源码
// Author(s):
// - Huailu Ren, hlren.pub@gmail.com
//
// 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 or posedge wb_rst_i) begin
if(wb_rst_i)
state <= IDLE;
else begin
case (state)
IDLE : begin
if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
state <= WE0;
else if (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 or posedge wb_rst_i) begin
if (wb_rst_i)
state_r <= IDLE;
else
state_r <= state;
end
//
// Write acknowledge
//
always @ (posedge wb_clk_i or posedge 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 <= #1 1'b1;
else
ack_we <= #1 1'b0;
end
//
// Read acknowledge
//
always @ (posedge wb_clk_i or posedge 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 <= #1 1'b1;
else
ack_re <= #1 1'b0;
end
always @ (posedge wb_clk_i or posedge 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 or posedge 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 or posedge 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 or posedge 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 or posedge 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 or posedge 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 or posedge 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 or posedge 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代码如下:
1 // Author(s):
2 // - Huailu Ren, hlren.pub@gmail.com
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 initial begin
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 initial begin
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作了以下简单的读写实验,测试代码如下所示
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 return 0;
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的控制代码如下
1 //----------------------------------------------------------------------------//
2 // Filename : ssram_wrapper.v //
3 // Author : Huailu Ren ...() //
4 // Email : hlren.pub@gmail.com //
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 output reg 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 else if (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平台)