Chinaunix首页 | 论坛 | 博客
  • 博客访问: 520626
  • 博文数量: 56
  • 博客积分: 1136
  • 博客等级: 少尉
  • 技术积分: 1378
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-28 14:02
文章存档

2014年(1)

2013年(7)

2012年(45)

2011年(3)

分类: 嵌入式

2012-06-11 10:09:56

机制和策略的分离的思想

 

在程序设计中,机制与策略分离的思想可以提高程序的可复用性,可维护性和可调试性使程序更具有高内聚低耦合性。如果说机制是砖,那么策略就是房子,同样的砖可以建不同的房子,我们不能把建砖和建房子混在一起实现,所以,把策略同机制揉成一团有两个负面影响:一来会使策略变得死板,难以适应用户需求的改变,二来也意味着任何策略的改变都极有可能动摇机制。

我们来举个例子看一下,这个思想所带来的好处,下面10年的时候写的一个小程序,当时我们接到一个要求在LCD指定位置上贴图的项目,硬件是采用xilinxxc3s50a芯片,数据源都放在SPI FlashS25FL064A)中,我的任务便是从这片Flash中读取所要求的数据,送到SDRAM中。

当时是分成两部分来完成的,一部分完成SPI Flash时序上的读写,属入机制,另一部分完成SPI Flash指定位置的数据读写,功能实现,属入策略,同一个机制可以适应不同的策略。

我们看机制实现:Flash_Controller.v

////////////////////////////////////////////////////////////////////////////////

// Company:         Ultrawise R&D Center

// Engineer:        Cheney

//

// Create Date:      09/29/2010

// Design Name:     SPI Flash Contorller

// Module Name:     flash_ctr

// Project Name:    OSD

// Target Devices:  xc3s50a-5vq100

// Tool versions:   ISE10.1

//

// Description:     This File is a SPI flash controler.

//                  SPI mode 3( CPOL = 1'b1;  CPHA = 1'b1;)

//                  System clock not more than 100M

// Dependencies:

//

// Revision:1.0

// Revision 0.1 - File Created

// Additional Comments:

//

// -----------------------------------------------------------------------------

// Revision History :

//------------------------------------------------------------------------------

// Ver  | Author    | Mod. Date | Changes Made:

//------------------------------------------------------------------------------

// 0.1  | Cheney    |  9/16/10  | birth

// 0.2  | Cheney    |  9/17/10  | Release

// 0.3  | Cheney    |  9/18/10  | Release

// 0.4  | Cheney    |  9/20/10  | Release

// 0.6  | Cheney    |  9/24/10  | Release

// 0.6.2| Cheney    |  9/24/10  | Release

// 0.7  | Cheney    |  9/26/10  | Release

// 1.0  | Cheney    |  9/29/10  | Release

//------------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////

//------------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////

 

`timescale 1ns / 1ps

 

module Flash_Controller(

    input               SysClk,     // System clock

    input               SysRst,     // System reset

    input      [31:0]   addr,           // picture address

    output reg [7:0]    d_out,          // Data ouput port

    output reg          PDF,            // Data ouput effective flag

    output reg          Dout_Flag,          // Data ouput effective flag

 

    input               RD_EN,       // read enable

    input                   Miso,        // Serial data output 

    output reg          Mosi,        // Serial data input    

    output reg          SpiClk,      // Serial clock

    output                  SpiWp_n,     // SPI write protect

    output reg          SpiCs_n      // SPI chip Select

);

 

    reg [7:0]           txdata;                // Transmit buffer

    reg [7:0]           rxdata;                // Receive buffer

    reg [31:0]          addr_temp;             // Address buffer

    reg [7:0]           BitCount;              // Bit counter

    reg [3:0]           receive_BitCount;      // Receive bit counter

 

   // SPI Serial clock flag

    reg [1:0]           SpiClk_flag;

    // SPI State

    reg [1:0]           Spi_State;

   

    parameter           idle            = 2'b00;

    parameter           send_cmd        = 2'b01;

    parameter           send_addr       = 2'b10;

    parameter           receive_data    = 2'b11;

   //SPI Read Data Bytes Command

    parameter           cmd             = 8'h0b;           

 

 

    assign SpiWp_n = 1'b1;

 

/***********************************************************************************************************

SPI state machine

Spansion SPI Mode 3(CPOL = 1, CPHA = 1 )

Read Data Bytes command 03H

The host system must first select the device by driving

SpiCs_n low.The READ command is then written to Mosi, followed by a 3-byte address (A23-A0). Each bit is

latched on the rising edge of SCK. The memory array data, at that address, are output serially on Miso at a

frequency fSCK, on the falling edge of SCK.

*************************************************************************************************************/

always @ ( posedge SysClk)begin

    if( SysRst )begin                                                   // System reset

        SpiCs_n          <= 1'b1;

        SpiClk           <= 1'b1;

        BitCount         <= 'd0;

        SpiClk_flag      <= 'd0;

        Spi_State        <= idle;

        PDF              <= 0;

        Dout_Flag        <= 'd0;

        receive_BitCount <= 'd7;

        rxdata           <= 'h00;

        end

   else begin

        case( Spi_State )

 

        idle :begin                                                 // Idle state

                SpiCs_n          <= 1'b1;

                SpiClk           <= 1'b1;

                BitCount         <= 'd0;

                SpiClk_flag      <= 'd0;

                PDF              <= 0;

                Dout_Flag        <= 'd0;

                receive_BitCount <= 'd7;

                if( RD_EN == 'b1 )begin

                    Spi_State[1:0]  <= send_cmd;

                    BitCount        <= 'd0;

                    SpiClk_flag     <= 0;

                    txdata          <= cmd;

                end

                else begin

                    Spi_State[1:0] <= idle;

                end

        end

         

        send_cmd :begin                                     // Send 8 bit command;

                SpiCs_n     <= 1'b0;

                SpiClk_flag <=SpiClk_flag+1;

                if(SpiClk_flag == 'd1)begin

                    SpiClk_flag <=0;

                    Mosi        <= txdata[7];

                    txdata      <= txdata<<1;

                    SpiClk      <= 1'b0;

                    BitCount    <= BitCount+1;

                end

                else begin

                    SpiClk  <= 1'b1;

                    if( BitCount == 8)begin

                        BitCount  <= 'd0;

                        Spi_State <= send_addr;

                        addr_temp <= addr;

                    end

                end 

        end

         

        send_addr :begin                                        // Send 24 bit address;

                SpiClk_flag <=SpiClk_flag+1;

                if(SpiClk_flag == 'd1)begin

                    Mosi        <= addr_temp[23];

                    SpiClk_flag <=0;

                    addr_temp   <= addr_temp<<1;

                    BitCount    <= BitCount+1;

                    SpiClk      <= 1'b0;

                    if( BitCount == 'd32)begin

                        BitCount  <= 'd0;

                        Spi_State <= receive_data;

                    end

                end

                else begin

                    SpiClk  <= 1'b1;

                end 

        end

         

        receive_data :begin                             //Receive 8 bit data;

                if(RD_EN==0) begin  Spi_State[1:0] <= idle; end

                SpiClk_flag <= SpiClk_flag+1;

                if(SpiClk_flag == 'd0)begin

                    SpiClk                      <= 1'b1;

                    rxdata[ receive_BitCount ]  <= Miso;

                    receive_BitCount            <= receive_BitCount - 'd1;

                    if( receive_BitCount ==0) begin receive_BitCount <=7; end

                    BitCount <= BitCount+1;

                    if( BitCount == 0)Dout_Flag<='d1;

                    if( BitCount == 8)begin BitCount <= 'd1; PDF <=1; end

                end

                else begin

                    SpiClk      <= 1'b0;

                    SpiClk_flag <='d0;

                    PDF         <=0;

                    if( BitCount == 8 )begin

                        d_out <= rxdata;

                    end

                end 

        end

        endcase

    end

end

endmodule

 

下面是策略实现:Flash_Top.v

////////////////////////////////////////////////////////////////////////////////

// Company:         Ultrawise R&D Center

// Engineer:        Cheney

//

// Create Date:      09/29/2010

// Design Name:      SPI Flash Contorl

// Module Name:     top_flash

// Project Name:    OSD

// Target Devices:  xc3s50a-5vq100

// Tool versions:   ISE10.1

// Description:      System clock not more than 100M

//

// The Top layer of design;

//

// Dependencies:

//

// Revision:1.0

// Revision 0.1 - File Created

// Additional Comments:

//

// -----------------------------------------------------------------------------

// Revision History :

//------------------------------------------------------------------------------

// Ver  | Author    | Mod. Date | Changes Made:

//------------------------------------------------------------------------------

// 0.1  | Cheney    |  9/16/10  | birth

// 0.2  | Cheney    |  9/17/10  | Release

// 0.3  | Cheney    |  9/18/10  | Release

// 0.4  | Cheney    |  9/20/10  | Release

// 0.5  | Cheney    |  9/22/10  | Release

// 0.6  | Cheney    |  9/24/10  | Release

// 0.6.2| Cheney    |  9/24/10  | Release

// 0.7  | Cheney    |  9/26/10  | Release

// 1.0  | Cheney    |  9/29/10  | Release

//------------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////

`timescale 1ns / 1ns

module Flash_Top(

      input             SysClk,     //system clock

      input             SysRst,     //system reset

      output            PDF,        //data ouput effective flag

      output  [7:0]     Data_Out,   //data ouput port

      output   reg      Pic_SAT,    // picture output flag

      input   [31:0]    EPI,        //EPI[31->6:a-z] letteer  EPI[5->0:bpa]

      /****SPI interface**************/

      input                 Miso,

      output                Mosi,

      output                SpiClk,

      output                SpiCs_n,

      output                SpiWp_n,

      /*********************************/

      input Flash_sdram_start,

//    output reg Sdram_read_start,

      output reg Flash_read_finished  

    );

 

 

    /********picturn address**********/

   

   //OSD picture address

    parameter   OSD_0     = 24'h000000;

   

    parameter   OSD_A     = 24'h0C2640;

   

    //Backgroud picture address

    parameter   BPA1      = 24'h21dbc0; 

   

   

   

    integer Pic_Count;

 

   

    reg             RD_EN;

    reg    [23:0]   addr;

    wire            Dout_Flag;

    reg    [2:0]    Pr_Mode;

    reg    [3:0]    delay;

   

   

    reg    [25:0]   osd_l_num ;

    reg    [5:0]    bpa_num;

/*****************************************************

OSD modle select AND display mode

*****************************************************/

always @ ( posedge SysClk)begin

    if( SysRst )begin

         Pic_Count <= 'd0;

          RD_EN   <= 'd0;

          Pic_SAT <= 'd0;

//        Sdram_read_start<= 'd0;

          Flash_read_finished <= 'd0;

         

          Pr_Mode <= 'd0;

          delay   <= 'd0;

        

    end

    else begin

           

 

          if(Flash_sdram_start=='d0)begin

          osd_l_num <=EPI[31:6];

          bpa_num <= EPI[5:0];

          end

        

          else begin

          if (Dout_Flag) begin Pic_SAT <= 'd1;

//        Sdram_read_start<= 'd1;

                                Flash_read_finished <= 'd1;

                         end

          if( PDF )begin

                Pic_Count <=Pic_Count + 'd1;

          end

         

          case (Pr_Mode)

         

          'd0: begin

                    addr <= OSD_0 ;

                    if(Pic_Count >= 'd54720 *13 +'d42432 *2 )begin

                        RD_EN   <= 'd0;

                        //Pic_SAT <= 'd0;

                        delay <= delay + 'd1;

                        if(delay >= 'd10)begin   // There is enough time for SPI state machine to idle state; 

                            Pic_Count <= 'd0;

                            Pr_Mode <='d1;        //

                            addr <= OSD_A ;

                        end

                    end

                    else RD_EN   <= 'd1;   

                 end

           

        'd1:begin

           

           case (osd_l_num[25] )

            'd1: begin

                 if(Pic_Count >= 'd54720 *1 )begin

                        RD_EN   <= 'd0;

                        //Pic_SAT <= 'd0;

                        delay <= delay + 'd1;

                        if(delay >= 'd10)begin  // There is enough time for SPI state machine to idle state; 

                            Pic_Count <= 'd0;

                            osd_l_num <= osd_l_num <<1;      //

                            addr <= addr + 'd54720;

                            delay <= 'd0;

                        end

                    end

                    else begin RD_EN   <= 'd1;   end

              end

             'd0: begin osd_l_num <= osd_l_num <<1; addr <= addr + 'd54720; 

                    if(osd_l_num=='d0) begin Pr_Mode <='d2; end

                    end

               

            endcase

            end

        

      'd2:begin

           addr <= BPA1 +'d391680 * bpa_num;

             if(Pic_Count >= 'd391680 *1 )begin

                        RD_EN   <= 'd0;

                        //Pic_SAT <= 'd0;

                        delay <= delay + 'd1;

                        if(delay >= 'd10)begin     // There is enough time for SPI state machine to idle state; 

                            Pic_Count <= 'd0;

                            delay <= 'd0;

                            Pr_Mode <='d3;

                        end

                end

                else RD_EN   <= 'd1;   

               

        end

      'd3: begin Pic_SAT <= 'd0;

//    Sdram_read_start<= 'd0;

                                Flash_read_finished <= 'd0;

          end

      default :;

      endcase

     

      end

    end

end

 

Flash_Controller Flash_Controller(

                    .SysClk(SysClk),

                    .SysRst(SysRst),

                    .addr({8'h00,addr}),

                    .d_out(Data_Out),

                    .PDF(PDF),

                    .Dout_Flag(Dout_Flag),

                    .RD_EN(RD_EN),

                    .SpiClk(SpiClk),

                    .Mosi(Mosi),

                    .Miso(Miso),

                    .SpiWp_n(SpiWp_n),

                    .SpiCs_n(SpiCs_n)

                    );

 

endmodule

 

 

阅读(5674) | 评论(1) | 转发(2) |
给主人留下些什么吧!~~