测试4线SPI tb代码

module tb_qspi1
(
/*
    input         I_clk         ,
    input         I_rst_n       ,

    output        O_qspi_clk    , // QPI总线串行时钟线
    output        O_qspi_cs     , // QPI总线片选信号
    inout         IO_qspi_io0   , // QPI总线输入/输出信号线
    inout         IO_qspi_io1    , // QPI总线输入/输出信号线
    inout         IO_qspi_io2    , // QPI总线输入/输出信号线
    inout         IO_qspi_io3      // QPI总线输入/输出信号线  
*/    
    
);
     
reg [3:0]   R_state             ;
reg [7:0]   R_flash_cmd         ;
reg [23:0]  R_flash_addr        ;
reg         R_clk_25M           ;
reg [4:0]   R_cmd_type          ;
reg    [15:0]    R_status_reg        ;
                                
wire        W_done_sig          ;
wire [7:0]  W_read_data         ;
wire        W_read_byte_valid   ;
wire [2:0]  R_qspi_state        ;

//                                   新增                                      //
reg I_clk;
wire O_qspi_clk  ;
wire O_qspi_cs   ;
wire IO_qspi_io0 ;
wire IO_qspi_io1 ;
wire IO_qspi_io2 ;
wire IO_qspi_io3 ;
reg I_rst_n;







//产生50mhz时钟//

initial
    I_clk=0;
always
    #10 I_clk=~I_clk;
    
//产生I_rst_n//
initial 
begin
    I_rst_n=0;
    #100 I_rst_n=1;
end





          
//功能:二分频逻辑          
          
always @(posedge I_clk or negedge I_rst_n)
begin
    if(!I_rst_n) 
        R_clk_25M   <=  1'b0        ;
    else 
        R_clk_25M   <=  ~R_clk_25M  ;
end



//功能:测试状态机

always @(posedge R_clk_25M or negedge I_rst_n)
begin
    if(!I_rst_n) 
        begin
            R_state         <=  4'd0        ;
            R_flash_addr    <=  24'd0       ;
            R_flash_cmd     <=  8'h00       ;
            R_cmd_type      <=  5'b0_0000   ;
        end
     else 
        begin
            case(R_state)           
                4'd0://读Device ID指令
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin 
                                R_flash_cmd  <= 8'h90           ; 
                                R_flash_addr <= 24'd0           ; 
                                R_cmd_type   <= 5'b1_0000       ; 
                            end     
                    end 
                4'd1://写不使能(Write disable)指令
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ;
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h04            ; 
                                R_cmd_type  <= 5'b1_0100        ; 
                            end     
                    end                
                4'd2://写使能(Write Enable)指令
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin
                                R_flash_cmd <= 8'h06            ; 
                                R_cmd_type  <= 5'b1_0001        ; 
                            end
                    end         
                4'd3:// 扇区擦除(Sector Erase)指令
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h20            ; 
                                R_flash_addr<= 24'd0            ; 
                                R_cmd_type  <= 5'b1_0010        ; 
                            end
                    end
            
                4'd4://读状态寄存器1, 当Busy位(状态寄存器1的最低位)为0时表示擦除操作完成
                    begin
                        if(W_done_sig) 
                            begin 
                                if(W_read_data[0]==1'b0) 
                                    begin 
                                        R_flash_cmd <= 8'h00            ; 
                                        R_state     <= R_state + 1'b1   ;
                                        R_cmd_type  <= 5'b0_0000        ; 
                                    end
                                else 
                                    begin 
                                        R_flash_cmd <= 8'h05        ; 
                                        R_cmd_type  <= 5'b1_0011    ; 
                                    end
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h05        ; 
                                R_cmd_type  <= 5'b1_0011    ; 
                            end
                    end
                4'd5://写状态寄存器2(Write Status Register2)指令,用来把QE(Quad Enable)位置1
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin
                                R_flash_cmd <= 8'h01            ; 
                                R_cmd_type  <= 5'b1_0110        ; 
                                R_status_reg<= 16'h0002            ;
                            end
                    end 
                4'd6://写使能(Write Enable)指令
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin
                                R_flash_cmd <= 8'h06            ; 
                                R_cmd_type  <= 5'b1_0001        ; 
                            end
                    end             
                4'd7: //四线模式页编程操作(Quad Page Program): 把存放在ROM中的数据写入QSPI Flash中
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ; 
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h32            ; 
                                R_flash_addr<= 24'd0            ; 
                                R_cmd_type  <= 5'b1_1000        ; 
                            end
                    end
                4'd8://读状态寄存器1, 当Busy位(状态寄存器1的最低位)为0时表示写操作完成
                    begin
                        if(W_done_sig) 
                            begin 
                                if(W_read_data[0]==1'b0) 
                                    begin 
                                        R_flash_cmd <= 8'h00            ; 
                                        R_state     <= R_state + 1'b1   ;
                                        R_cmd_type  <= 5'b0_0000        ; 
                                    end
                                else 
                                    begin 
                                        R_flash_cmd <= 8'h05        ; 
                                        R_cmd_type  <= 5'b1_0011    ; 
                                    end
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h05        ; 
                                R_cmd_type  <= 5'b1_0011    ; 
                            end
                    end           
                4'd9://四线模式读256 Bytes数据
                    begin
                        if(W_done_sig) 
                            begin 
                                R_flash_cmd <= 8'h00            ; 
                                R_state     <= R_state + 1'b1   ;
                                R_cmd_type  <= 5'b0_0000        ; 
                            end
                        else 
                            begin 
                                R_flash_cmd <= 8'h6b            ; 
                                R_flash_addr<= 24'd0            ; 
                                R_cmd_type  <= 5'b1_1001        ; 
                            end
                    end
            
                4'd10:// 结束状态
                    begin
                        R_flash_cmd <= 8'h00            ; 
                        R_state     <= 4'd10            ;
                        R_cmd_type  <= 5'b0_0000        ; 
                    end
                default :   R_state     <= 4'd0         ;
            endcase
        end           
end 
qspi1 u_qspi1
(
.O_qspi_clk          (O_qspi_clk        ), // QPI总线串行时钟线
.O_qspi_cs           (O_qspi_cs         ), // QPI总线片选信号
.IO_qspi_io0         (IO_qspi_io0       ), // QPI总线输入/输出信号线
.IO_qspi_io1         (IO_qspi_io1       ), // QPI总线输入/输出信号线
.IO_qspi_io2         (IO_qspi_io2       ), // QPI总线输入/输出信号线
.IO_qspi_io3         (IO_qspi_io3       ), // QPI总线输入/输出信号线
                   
.I_rst_n             (I_rst_n           ), // 复位信号

.I_clk_25M           (R_clk_25M         ), // 25MHz时钟信号
.I_cmd_type          (R_cmd_type        ), // 命令类型
.I_cmd_code          (R_flash_cmd       ), // 命令码
.I_qspi_addr         (R_flash_addr      ), // QSPI Flash地址
.I_status_reg         (R_status_reg        ), // QSPI Flash状态寄存器

.O_done_sig          (W_done_sig        ), // 指令执行结束标志
.O_read_data         (W_read_data       ), // 从QSPI Flash读出的数据
.O_read_byte_valid   (W_read_byte_valid ), // 读一个字节完成的标志
.O_qspi_state        (R_qspi_state      )  // 状态机,用于在顶层调试用
);
     
wire [35:0]     CONTROL0    ;
wire [99:0]     TRIG0       ;
icon icon_inst (
    .CONTROL0(CONTROL0) // INOUT BUS [35:0]
);

ila ila_inst (
    .CONTROL(CONTROL0)  , // INOUT BUS [35:0]
    .CLK(I_clk)           ,      // IN
    .TRIG0(TRIG0)      // IN BUS [255:0]
);                                                     

assign  TRIG0[7:0]      =   W_read_data         ;                                               
assign  TRIG0[8]        =   W_read_byte_valid   ;   
assign  TRIG0[12:9]     =   R_state             ;        
assign  TRIG0[16:13]    =   R_qspi_state        ;   
assign  TRIG0[17]       =   W_done_sig          ;    
assign  TRIG0[18]       =   IO_qspi_io0         ;  
assign  TRIG0[19]       =   IO_qspi_io1         ;  
assign  TRIG0[20]       =   IO_qspi_io2         ;  
assign  TRIG0[21]       =   IO_qspi_io3         ;  
assign  TRIG0[22]       =   O_qspi_cs           ;  
assign  TRIG0[23]       =   O_qspi_clk          ; 
assign  TRIG0[28:24]    =   R_cmd_type          ; 
assign  TRIG0[36:29]    =   R_flash_cmd         ; 
assign  TRIG0[60:37]    =   R_flash_addr        ; 
assign  TRIG0[61]       =   I_rst_n             ; 
assign  TRIG0[77:62]    =   R_status_reg        ; 


endmodule

你可能感兴趣的:(fpga开发)