FPGA学习笔记之flash

module SIM_spi_flash_TB();
localparam  P_CLK_CYCLE =20;
reg  clk,rst;

initial 
begin
    rst ='d1;
    #100;
    @(posedge clk) rst='d0;
    
end

localparam                      P_OP_TYPE_INS   =0,
                                P_OPREAD        =1,
                                P_OP_WRITE      =2;

always
begin
      clk =0;
      #(P_CLK_CYCLE/2);
      clk=1;
      #(P_CLK_CYCLE/2);
end
reg    [31:0] i_user_op_data  ;
reg    [1:0]  i_user_op_type  ;
reg    [15:0] i_user_op_len   ;
reg    [15:0] i_user_clk_len  ;
reg           i_user_op_valid ;
reg [7:0]             r_user_data  ;
reg                   r_user_valid;
reg                i_user_write_data;
reg                r_user_read_data;
                 
wire          o_user_op_ready ;
wire                  w_spi_clk;
wire                  w_spi_cs ;
wire                  w_spi_mosi;
wire                  w_user_ready      ;
wire [7:0]            w_user_read_data ;
wire                  w_user_read_valid;
wire                  w_user_active;
wire                  o_user_write_req;


assign         w_user_active = i_user_op_valid&o_user_op_ready;

spi_flash_drive#(
      .                          P_DATA_WIDTH      (8),
      .                          P_CPOL            (0),
      .                          P_READ_DATA_WIDTH (8),
      .                          P_CPHL            (0),
      .                          P_OP_LEN          (32)

)
spi_flash_drive_u0
(
     .             i_clk     (clk),
     .             i_rst     (rst),


     .             o_spi_clk (  ) ,
     .             o_spi_cs  ( ),
     .             o_spi_mosi(),
     .             i_spi_miso(),
     .             i_user_op_data       (i_user_op_data  ),
     .             i_user_op_type       (i_user_op_type  ),
     .             i_user_op_len        (i_user_op_len   ),
     .             i_user_clk_len       (i_user_clk_len  ),
     .             i_user_op_valid      (i_user_op_valid ),
     .             o_user_op_ready      (o_user_op_ready ),

  
   
     .             o_user_read_data (w_user_read_data),
     .             o_user_read_valid(w_user_read_valid),
     .             i_user_write_data(i_user_write_data),
     .             o_user_write_req (o_user_write_req)
    );


    always@(posedge clk, posedge rst)
    begin
        if(rst)
            i_user_op_valid <= 'd0;
        else if(o_user_op_ready)
            i_user_op_valid <= 'd1;
        else 
            i_user_op_valid <= 'd0;
    end

   always@(posedge clk, posedge rst)
    begin
        if(rst)begin
          i_user_op_data <= 'd0;
          i_user_op_type <= 'd0;
          i_user_op_len  <= 'd0;
          i_user_clk_len <= 'd0;
        end

        else if(o_user_op_ready)begin
             i_user_op_data <= {8'h55,8'h01,8'h02,8'h03};
             i_user_op_type <= P_OP_WRITE;
             i_user_op_len  <= 'd32;
             i_user_clk_len <= 32+(8<<(2-1));
        end 
        else  begin
             i_user_op_data <=  i_user_op_data ;
             i_user_op_type <=  i_user_op_type ;
             i_user_op_len  <=  i_user_op_len  ;
             i_user_clk_len <=  i_user_clk_len ;
        end 

    end

always@(posedge clk,posedge rst)
begin
    if(rst)
        i_user_write_data <='d0;
    else if(o_user_write_req)
        i_user_write_data <= i_user_write_data+1;
    else 
        i_user_write_data <= i_user_write_data;
end 

always@(posedge clk,posedge rst)
begin
    if(rst)
        r_user_read_data <='d0;
    else if(o_user_read_valid)
        r_user_read_data <=o_user_read_data;
    else 
        r_user_read_data <= r_user_read_data;
end 

endmodule
module spi_flash_top(

  input               i_clk,
  output             o_spi_clk,
  output             o_spi_cs,
  output             o_spi_mosi,
  input              i_spi_miso

);

wire             w_clk_5Mhz;
wire             w_clk_5Mhz_lock;
wire                  w_user_ready      ;
wire [7:0]            w_user_read_data ;
wire                  w_user_read_valid;
SYSTEM_CLK SYSTEM_CLK_U0
   (
    .clk_in1(i_clk),
    // Clock out ports
    .clk_out1(clk_out1),     // output clk_out1
    // Status and control signals
    .locked( w_clk_5Mhz_lock)       // output locked
   // Clock in ports
    
    );      // input clk_in1


spi_flash_drive#(
      .                          P_DATA_WIDTH      (8),
      .                          P_CPOL            (0),
      .                          P_READ_DATA_WIDTH (8),
      .                          P_CPHL            (0)

)
spi_flash_drive_u0
(
     .             i_clk     (clk),
     .             i_rst     ( ~w_clk_5Mhz_lock),


     .             o_spi_clk (o_spi_clk)   ,
     .             o_spi_cs  (o_spi_cs),
     .             o_spi_mosi(o_spi_mosi),
     .             i_spi_miso(i_spi_miso),


 
     .                     o_user_read_data (w_user_read_data),
     .                     o_user_read_valid(w_user_read_valid)
    );


endmodule

 

 


module spi_flash_drive#(

 parameter                      P_DATA_WIDTH=8,
                                P_CPOL      =0,
                                P_READ_DATA_WIDTH =8,
                                P_CPHL      =0,
                                P_OP_LEN    =32

)
(
     input              i_clk,
     input              i_rst,


     output             o_spi_clk,
     output             o_spi_cs,
     output             o_spi_mosi,
     input              i_spi_miso,

     input   [P_OP_LEN -1:0]     i_user_op_data,
     input    [1:0]              i_user_op_type,
     input    [15:0]             i_user_op_len,
     input    [15:0]             i_user_clk_len,
     input                       i_user_op_valid,
     output                      o_user_op_ready,

    input  [P_DATA_WIDTH-1:0]    i_user_write_data,
    output                       o_user_write_req,
 

    

    output [P_READ_DATA_WIDTH-1:0]  o_user_read_data,
    output                          o_user_read_valid
    );

    
/***************function**************/

/***************parameter*************/
localparam                      P_OP_TYPE_INS   =0,
                                P_OP_READ        =1,
                                P_OP_WRITE      =2;
/***************port******************/             

/***************mechine***************/

/***************reg*******************/
reg                    ro_spi_clk;
reg                    ro_spi_cs;
reg                    ro_spi_mosi;
reg                    ro_user_ready;
reg  [P_DATA_WIDTH-1:0]  r_user_data;
reg  [P_OP_LEN-1:0]            r_user_op_data; 
reg   [1:0]                    r_user_op_type;
reg   [15:0]                   r_user_op_len;
reg   [15:0]                   r_user_clk_len; 
reg                     r_run;
reg [15:0]               r_cnt;
reg                   r_spi_cnt;
reg [P_DATA_WIDTH-1:0]   ro_user_read_data;
reg                      ro_user_read_valid;  
reg                     r_run_1d;
reg                     ro_user_write_req;
reg                     ro_user_write_req_1d;
reg   [15:0]            r_write_cnt;
reg   [P_DATA_WIDTH-1:0]    r_user_write_data;
reg                        r_read_cnt;
/***************wire******************/
wire           w_user_active;
wire           w_run_negedge;


/***************component*************/

/***************assign****************/
assign      o_spi_clk           =   ro_spi_clk;   
assign      o_spi_cs            =   ro_spi_cs;
assign      o_spi_mosi          =   ro_spi_mosi;
assign      o_user_op_ready        =   ro_user_ready;   
assign      w_user_active       =   i_user_op_valid &  o_user_op_ready; 
assign      o_user_read_data    =   ro_user_read_data;
assign      o_user_read_valid   =   ro_user_read_valid;
assign      w_run_negedge       =   !r_run &r_run_1d;
assign      o_user_write_req    =   ro_user_write_req;
/***************always****************/

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
    begin
        
          r_user_op_type <= 'd0;
          r_user_op_len  <= 'd0;
          r_user_clk_len <= 'd0;
    end
    else if(w_user_active) begin
       
        r_user_op_type <=i_user_op_type ;
        r_user_op_len  <=i_user_op_len  ;
        r_user_clk_len <=i_user_clk_len ;
      
    end
   // else if(r_spi_cnt)
       // r_user_data <=r_user_data <<1;
    else begin
           
            r_user_op_type <=r_user_op_type;
            r_user_op_len  <=r_user_op_len ;
            r_user_clk_len <=r_user_clk_len;        
    end
        
end
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
       r_user_op_data <= 'd0;
    else if(ro_user_write_req_1d)
       r_user_op_data<= i_user_op_data;
    else if(r_spi_cnt)
       r_user_op_data <= r_user_op_data <<1;
    else 
      r_user_op_data <= r_user_op_data;
end 

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_run<='d0;
    else if(r_spi_cnt && r_cnt==r_user_clk_len-1)
        r_run<='d0;
    else  if(w_user_active)
        r_run<='d1;
    else 
        r_run<=r_run;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_run_1d <='d0;
    else 
        r_run_1d<=r_run;
end


always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_cnt<='d0;
    else if(r_spi_cnt && r_cnt==r_user_clk_len-1)
        r_cnt<='d0;
    else  if(r_spi_cnt)
        r_cnt<=r_cnt+1;
    else 
        r_cnt<=r_cnt;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_spi_cnt<='d0;
    else if(r_run)
        r_spi_cnt<=r_spi_cnt+1;
    else 
        r_spi_cnt<='d0;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
       ro_spi_clk <=P_CPOL ;
    else if(r_run)
        ro_spi_clk <= ~ ro_spi_clk ;
    else 
        ro_spi_clk <=P_CPOL ;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
       ro_spi_cs <='d1 ;
         else  if(w_user_active)
       ro_spi_cs <='d0;
       
    else if(!r_run)
       ro_spi_cs <= 'd1;
      
   
    else 
       ro_spi_cs <= ro_spi_cs ;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
       ro_spi_mosi <= 'd0;
    else if(w_user_active)
       ro_spi_mosi <=i_user_op_data[P_OP_LEN-1];
    else  if(r_spi_cnt && r_cnt < r_user_op_len)
       ro_spi_mosi <=r_user_op_data[P_OP_LEN-2];
    else if(r_user_op_type == P_OP_WRITE && r_spi_cnt)
       ro_spi_mosi<= r_user_write_data[7];
    else 
       ro_spi_mosi <= ro_spi_mosi;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ro_user_write_req <= 'd0;
    else if(r_cnt >= r_user_clk_len-5)
         ro_user_write_req <= 'd0;
    else if((!r_spi_cnt&&r_cnt==30) || r_write_cnt == 15)
        ro_user_write_req <='d1;
    else 
        ro_user_write_req <= 'd0;

end 

always@(posedge i_clk,posedge i_rst)
begin
     if(i_rst )
         ro_user_write_req_1d<='d0;
      else 
         ro_user_write_req_1d <= ro_user_write_req_1d;
end 

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_user_write_data<='d0;
    else if(ro_user_write_req_1d)
        r_user_write_data<=i_user_write_data;
    else  if(r_spi_cnt)
    r_user_write_data <=r_user_write_data<<1;
    else 
    r_user_write_data<=r_user_write_data;
end
/*always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_write_cnt <='d0;
    else if(r_write_cnt == P_DATA_WIDTH -1)
        r_write_cnt <= 'd0;
    else if((ro_user_write_req || (r_write_cnt&&r_spi_cnt) )&& r_spi_cnt &&r_user_op_type ==P_OP_WRITE)
        r_write_cnt <= r_write_cnt+1;
    else
        r_write_cnt <= r_write_cnt;

end
*/

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_write_cnt <='d0;
    else if(r_write_cnt == 15 || ro_spi_cs)
     r_write_cnt <='d0;
    else if(ro_user_write_req ||r_write_cnt>0)
        r_write_cnt <= r_write_cnt +1;
    else 
        r_write_cnt<=r_write_cnt;
end


always@(posedge ro_spi_clk,posedge i_rst)
begin
    if(i_rst)
      ro_user_read_data <= 'd0;
    //else if(r_spi_cnt)
    else if(r_cnt>=P_OP_LEN-1)
     ro_user_read_data <= {ro_user_read_data[P_DATA_WIDTH-2:0],i_spi_miso};
   // else  if(w_user_active)
   else 
    ro_user_read_data <= ro_user_read_data;
  
end

always@(posedge ro_spi_clk, posedge i_rst)
begin
     if(i_rst)
        r_read_cnt <='d0;
     else if(r_read_cnt ==7)
        r_read_cnt <='d0;
     else if(r_cnt>=P_OP_LEN-1)
        r_read_cnt <= r_read_cnt +1;
     else 

end

always@(posedge ro_spi_clk,posedge i_rst)
begin
    if(i_rst)
        ro_user_read_valid <= 'd0;
    else if(r_read_cnt ==7)
         ro_user_read_valid <= 'd1;
    else 
         ro_user_read_valid <= 'd0;
end 

always@(posedge i_clk,posedge i_rst)
begin
      if(i_rst)
      ro_user_read_valid <='d0;
      else if(r_spi_cnt && r_cnt==7)
      ro_user_read_valid <='d1;
      else 
      ro_user_read_valid <= 'd0;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
       ro_user_ready <= 'd1;
    else if(w_user_active)
       ro_user_ready <='d0;
    else if(w_run_negedge)
       ro_user_ready <='d1;
    else 
       ro_user_ready <=ro_user_ready ;
end

endmodule

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值