原创 如何在DE2平台上存取SDRAM? (IC Design) (DE2)

2009-9-25 10:41 4164 5 6 分类: 通信

Abstract
之前討論過在DE2用軟體的C語言存取SDRAM,本文討論用硬體的Verilog存取SDRAM。


Introduction
使用環境:Quartus II 7.2 SP1 + MegaCore IP 7.2 SP1 + DE2(Cyclone II EP2C35F627C6)

由於DE2的Cyclone II是個FPGA,為了硬體加速,有時可能會想將演算法用硬體Verilog實現,這時就得用硬體Verilog去直接存取SDRAM。

如同上一篇的範例,用switch當成2進位的輸入,但這次改用七段顯示器做16進位輸出。
Verilog / SDRAM_HR_HW.v



  1 /* 
  2 (C) OOMusou 2008 http://oomusou.cnblogs.com
  3 
  4 Filename    : SDRAM_HR_HW.v
  5 Compiler    : Quartus II 7.2 SP1
  6 Description : Demo how to use abstract base class simulate interface
  7 Release     : 04/25/2008 1.0
  8 */
  9 module SDRAM_HR_HW (
 10   input         CLOCK_50,
 11   input  [3:0]  KEY,
 12   input  [17:0] SW,
 13   output [17:0] LEDR,
 14   output [6:0]  HEX0,
 15                 HEX1,
 16                 HEX2,
 17                 HEX3,
 18                 HEX4,
 19                 HEX5,
 20                 HEX6,
 21                 HEX7,
 22   //SDRAM side
 23   output [11:0] DRAM_ADDR,
 24   inout  [15:0] DRAM_DQ,
 25   output        DRAM_BA_0,
 26                 DRAM_BA_1,
 27                 DRAM_RAS_N,
 28                 DRAM_CAS_N,
 29                 DRAM_CKE,
 30                 DRAM_CLK,
 31                 DRAM_WE_N,
 32                 DRAM_CS_N,
 33                 DRAM_LDQM,
 34                 DRAM_UDQM
 35 );
 36 
 37 wire        RESET_n = KEY[0];
 38 wire        DONE;     // write / read done
 39 reg  [22:0] addr;     // address regitster
 40 reg         read,     // read enable register
 41             write;    // write enable register
 42 reg  [1:0]  state;    // FSM state register
 43 reg  [15:0] data_in;  // data input register
 44 wire [15:0] DATA_OUT; // data output
 45 reg  [15:0] data_out; // data output register
 46 
 47 assign LEDR = SW;
 48 
 49 Sdram_Controller u0 (
 50   // HOST
 51   .REF_CLK(CLOCK_50), //system clock
 52   .RESET_N(RESET_n),  //system reset
 53   .ADDR(address),     //address for controller request
 54   .WR(write),         //write request
 55   .RD(read),          //read request
 56   .LENGTH(8'h02),     //request data length
 57   .ACT(),             //SDRAM ACK(acknowledge)
 58   .DONE(DONE),        //write/read done
 59   .DATAIN(data_in),   //Data input
 60   .DATAOUT(DATA_OUT), //Data output
 61   .IN_REQ(),          //input data request
 62   .OUT_VALID(),       //output data vilid
 63   .DM(2'b00),         //Data mask input
 64   // SDRAM
 65   .SA(DRAM_ADDR),
 66   .BA({DRAM_BA_1,DRAM_BA_0}),
 67   .CS_N(DRAM_CS_N),
 68   .CKE(DRAM_CKE),
 69   .RAS_N(DRAM_RAS_N),
 70   .CAS_N(DRAM_CAS_N),
 71   .WE_N(DRAM_WE_N),
 72   .DQ(DRAM_DQ),
 73   .DQM({DRAM_UDQM,DRAM_LDQM}),
 74   .SDR_CLK(DRAM_CLK)
 75 );
 76 
 77 SEG7_LUT_8 u1 (
 78   .oSEG0(HEX0),      // output SEG0
 79   .oSEG1(HEX1),      // output SEG1
 80   .oSEG2(HEX2),      // output SEG2
 81   .oSEG3(HEX3),      // output SEG3
 82   .oSEG4(HEX4),      // output SEG4
 83   .oSEG5(HEX5),      // output SEG5
 84   .oSEG6(HEX6),      // output SEG6
 85   .oSEG7(HEX7),      // output SEG7
 86   .iDIG(data_out),   // input data
 87   .iWR(1'b1),        // write enable
 88   .iCLK(CLOCK_50),   // clock
 89   .iRESET_n(RESET_n) // RESET
 90 );
 91 
 92 // state 0 : prepare write
 93 // state 1 : read switch & write SDRAM
 94 // state 2 : prepare read
 95 // state 3 : read SDRAM & write to SEG7
 96 always @(posedge CLOCK_50 or negedge RESET_n)
 97 begin
 98   if (!RESET_n) begin
 99     addr    <= 0// address register
100     read    <= 0// read enable register
101     write   <= 0// write enale register
102     state   <= 0// FSM state register
103     data_in <= 0// data input register
104   end
105   else
106   begin
107     case (state)
108       // state 0 : prepare write
109       0: begin
110         read  <= 0// read diable
111         write <= 1// write enable
112         state <= 1// next state
113       end
114       
115       //state 1 : read switch & write SDRAM
116       1: begin
117         if (DONE)  // prepared done
118         begin
119           addr    <= {23{1'b0}}; // write SDRAM address
120           data_in <= {SW[15:0]}; // write SDRAM data
121           
122           // ensure done change to 0
123           read    <= 0;          // read disable
124           write   <= 0;          // write disable
125           state   <= 2;          // next state
126         end
127       end
128       
129       // state 2 : prepare read
130       2: begin
131         read  <= 1// read enable
132         write <= 0// write disable
133         state <= 3// next state
134       end
135 
136       // state 3 : read SDRAM & write to SEG7
137       3: begin
138         if (DONE) begin
139           addr     <= {23{1'b0}}; // read SDRAM address
140           data_out <= DATA_OUT;   // read SDRAM data
141           
142           read     <= 0;          // read disable
143           write    <= 0;          // write disable
144           state    <= 0;          // next state
145         end
146       end
147     endcase
148   end
149 end
150 
151 endmodule


49行


Sdram_Controller u0 (
  
// HOST
  .REF_CLK(CLOCK_50), //system clock
  .RESET_N(RESET_n),  //system reset
  .ADDR(address),     //address for controller request
  .WR(write),         //write request
  .RD(read),          //read request
  .LENGTH(8'h02),     //request data length
  .ACT(),             //SDRAM ACK(acknowledge)
  .DONE(DONE),        //write/read done
  .DATAIN(data_in),   //Data input
  .DATAOUT(DATA_OUT), //Data output
  .IN_REQ(),          //input data request
  .OUT_VALID(),       //output data vilid
  .DM(2'b00),         //Data mask input
  // SDRAM
  .SA(DRAM_ADDR),
  .BA({DRAM_BA_1,DRAM_BA_0}),
  .CS_N(DRAM_CS_N),
  .CKE(DRAM_CKE),
  .RAS_N(DRAM_RAS_N),
  .CAS_N(DRAM_CAS_N),
  .WE_N(DRAM_WE_N),
  .DQ(DRAM_DQ),
  .DQM({DRAM_UDQM,DRAM_LDQM}),
  .SDR_CLK(DRAM_CLK)
);


我們引進了Sdram_Controller,這是個2 port的controller,1 read 1 write,大部分狀況下,2 port已經夠用,4 port的我會另外討論。

77行


SEG7_LUT_8 u1 (
  .oSEG0(HEX0),      
// output SEG0
  .oSEG1(HEX1),      // output SEG1
  .oSEG2(HEX2),      // output SEG2
  .oSEG3(HEX3),      // output SEG3
  .oSEG4(HEX4),      // output SEG4
  .oSEG5(HEX5),      // output SEG5
  .oSEG6(HEX6),      // output SEG6
  .oSEG7(HEX7),      // output SEG7
  .iDIG(data_out),   // input data
  .iWR(1'b1),        // write enable
  .iCLK(CLOCK_50),   // clock
  .iRESET_n(RESET_n) // RESET
);


引進了之前所寫的七段顯示器module,將output用七段顯示器表示。

91行


// state 0 : prepare write
// state 1 : read switch & write SDRAM
// state 2 : prepare read
// state 3 : read SDRAM & write to SEG7
always @(posedge CLOCK_50 or negedge RESET_n)
begin
  
if (!RESET_n) begin
    addr    
<= 0// address register
    read    <= 0// read enable register
    write   <= 0// write enale register
    state   <= 0// FSM state register
    data_in <= 0// data input register
  end
  
else
  begin
    
case (state)
      
// state 0 : prepare write
      0: begin
        read  
<= 0// read diable
        write <= 1// write enable
        state <= 1// next state
      end
      
      
//state 1 : read switch & write SDRAM
      1: begin
        
if (DONE)  // prepared done
        begin
          addr    
<= {23{1'b0}}; // write SDRAM address
          data_in <= {SW[15:0]}; // write SDRAM data
          
          
// ensure done change to 0
          read    <= 0;          // read disable
          write   <= 0;          // write disable
          state   <= 2;          // next state
        end
      end
      
      
// state 2 : prepare read
      2: begin
        read  
<= 1// read enable
        write <= 0// write disable
        state <= 3// next state
      end

      
// state 3 : read SDRAM & write to SEG7
      3: begin
        
if (DONE) begin
          addr     
<= {23{1'b0}}; // read SDRAM address
          data_out <= DATA_OUT;   // read SDRAM data
          state    <= 0;          // next state
        end
      end
    endcase
  end
end


我們採用了FSM,對SDRAM做存取。
1.當state為0時,送出寫入準備信號。
2.當state為1時,讀取switch值並寫入SDRAM。
3.當state為2時,送出讀取準備信號。
4.當state為3時,讀取SDRAM並回到state 0。

108行


0: begin
  read  
<= 0// read diable
  write <= 1// write enable
  state <= 1// next state
end


當state為0時,read <= 0;,write <= 1;表示準備寫入SDRAM,state <= 1;進入下一個state。

115行


//state 1 : read switch & write SDRAM
1: begin
  
if (DONE)  // prepared done
  begin
    addr    
<= {23{1'b0}}; // write SDRAM address
    data_in <= {SW[15:0]}; // write SDRAM data
          
    
// ensure done change to 0
    read    <= 0;          // read disable
    write   <= 0;          // write disable
    state   <= 2;          // next state
  end
end


這是本程式最重要的一段程式碼。

當state為1時,對SDRAM正式寫入。

當DONE為0時,表示SDRAM還無法讀寫,必須先回到state 0做寫入準備,或state 2做讀取準備,等到DONE為1時才可對SDRAM作正常讀寫。

addr為指定寫入SDRAM的記憶體位址,data_in為欲寫入SDRAM的資料。DE2上的SDRAM容量為8 MB,由4個bank所組成,addr[22:20]為bank數,addr[19:0]為每個bank內的記憶體位址。

最後須將 read <= 0;與wrie <= 0;讓DONE還原成0,因為在Sdram_Controller.v的245行


if(!WR && !RD)
  mDONE
<=0;


DONE變成0,SDRAM可重新做讀取與寫入準備。最後 state <= 2;進入下一個state。

130行


// state 2 : prepare read
2: begin
  read  
<= 1// read enable
  write <= 0// write disable
  state <= 3// next state
end


道理同state 0,但此時是做讀取準備。

137行



// state 3 : read SDRAM & write to SEG7
3: begin
  
if (DONE) begin
    addr     
<= {23{1'b0}}; // read SDRAM address
    data_out <= DATA_OUT;   // read SDRAM data
          
    read     
<= 0;          // read disable
    write    <= 0;          // write disable
    state    <= 0;          // next state
  end
end


道理同state 1,但此時是從SDRAM讀取資料,從DATA_OUT讀取資料進register後,回到state 0。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2013-4-27 15:47

请问你的代码可以用的吗?
相关推荐阅读
用户1005085 2010-08-27 11:15
红格人脸识别考勤机
        红格TR-0202C 作为第四代考勤机的领跑者不负众望,红格-TR0202C正式面市。这款考勤机采用了国内外最先进的技术,以及完全自主知识产权的红格人脸识别算法,既具有指纹考勤机的防打...
用户1005085 2009-09-25 10:34
如何产生VGA的Color Pattern Generator? (SOC) (Verilog)
Abstract本文使用Verilog在VGA產生Color Pattern Generator。Introduction使用環境:Quartus II 8.0 + DE2(Cyclone II EP...
用户1005085 2009-09-24 16:20
在ALTERA-DE2上实现VGA的颜色输出变化(verilog)
在我的DE2平台上验证过,可行!Abstract在友晶科技的DE2_CCD範例中,將CMOS的影像直接在VGA輸出,是否能控制VGA的座標,並顯示不同的影像呢?Introduction版權聲明:本文根...
用户1005085 2009-09-23 19:10
在ALTERA-DE2平台上实时产生灰阶图像
参考了一片文章,我在DE2平台上实际测试可行。和大家一起分享!Abstract灰階影像是很多電腦視覺演算法的基礎,必須會先會產生灰階影像後,才能繼續動其他演算法。Introduction使用環境:Qu...
用户1005085 2009-09-22 13:46
在ALTERA-DE2开发板上实现图像采集显示功能
DE2可外接摄像头模组和彩色LCD,如此可實作出簡單的數位相機,本篇先介紹使用Verilog純硬體的方式讓CCD影像顯示在彩色 LCD上。 使用環境:Quartus II 7.2 SP1 + Nios...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条