Verilog 异步FIFO问题

图片说明
我是刚进公司实习生,之前没怎么接触过verilog语言,今天师傅让我写这三个模块,说让我看看spi,异步FIFO,我感觉懵懵的,下不了手
其中spi依葫芦画瓢写出来了?那两个模块还不知道咋写?

师傅又说我可以写个测试文档
我现在脑袋里装满了问号?有没有大神指点一下 给我指条路 我接下来该怎么学习这一块知识 ?(我之前专业是信息工程 硬件只学了皮毛 数电 VHDL)
贴一下 spi那一块代码

module SPI
(

    input               I_clk       , //时钟信号
    input               I_rst       , //复位
    input               I_rx_en     , //允许读数据
    input               I_tx_en     , //允许发数据
    input        [7:0]  I_data_in   , //
    output  reg  [7:0]  O_data_out  , //
    output  reg         O_tx_done   , //传输完成标志
    output  reg         O_rx_done   , //读取完成标志

    //  spi信号定义
     output   reg        O_CS        ,//片选
     output   reg        O_SCLK      ,//时钟
     output   reg        O_SDI       ,//输出
     input               I_SDO       //输入 
);
    //0-15读写状态选择
    reg[3:0]            R_tx_state;
     reg[3:0]            R_rx_state;

 always@(posedge I_clk or negedge I_rst)
    begin 
     if(!I_rst)     //复位响应
      begin
           R_tx_state  <=  4'd0       ;
         R_rx_state  <=  4'd0       ;
            O_data_out  <=  8'd0       ;
          O_tx_done   <=  1'd0       ;
         O_rx_done   <=  1'd0       ;
           O_SDI       <=  1'd0       ;
            O_SCLK      <=  1'd0       ;
            O_CS        <=  1'd1       ;
         end
      else if(I_tx_en)//发信号
         begin
          O_CS        <=  1'd0       ;
             case (R_tx_state)
                    4'd1, 4'd3 , 4'd5 , 4'd7  , 4'd9, 4'd11, 4'd13, 4'd15 : //整合奇数
                      begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                               O_SCLK        <=  1'b1                ;
                        end
                      4'd0: //第七位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[0]       ;
                               O_SCLK        <=  1'b0                ;
                              end

                      4'd2: //第六位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[1]       ;
                               O_SCLK        <=  1'b0                ;
                              end
                      4'd4: //第五位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[2]       ;
                               O_SCLK        <=  1'b0                ;
                              end
                      4'd6: //第四位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[3]       ;
                                O_SCLK        <=  1'b0                ;
                              end
                      4'd8: //第三位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[4]       ;
                                O_SCLK        <=  1'b0                ;
                              end
                      4'd10: //第二位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[5]       ;
                               O_SCLK        <=  1'b0                ;
                              end
                      4'd12: //第一位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b0                ;
                           O_SDI         <=  O_data_out[6]       ;
                               O_SCLK        <=  1'b0                ;
                              end
                      4'd14: //第零位
                            begin
                        R_tx_state    <=  R_tx_state + 1'b1   ;
                        O_tx_done     <=  1'b1                ;
                           O_SDI         <=  O_data_out[7]       ;
                               O_SCLK        <=  1'b0                ;
                              end
                    default: R_tx_state    <=  4'd0                ;
                endcase
            end
    else if(I_rx_en)//收信号  
           begin
            O_CS    <=  1'b0        ; // 拉低片选信号CS
            case(R_rx_state)
                4'd0, 4'd2 , 4'd4 , 4'd6  ,  4'd8, 4'd10, 4'd12, 4'd14 : //整合偶数状态
                    begin
                        O_SCLK          <=   1'b0                ;
                        R_rx_state      <=   R_rx_state + 1'b1   ;
                        O_rx_done       <=   1'b0                 ;
                    end
                4'd1:    // 接收第7位
                    begin                       
                        O_SCLK          <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[7]   <=  I_SDO               ;   
                    end
                4'd3:    // 接收第6位
                    begin
                        O_SCLK          <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[6]   <=  I_SDO               ; 
                    end
                4'd5:    // 接收第5位
                    begin
                        O_SCLK          <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[5]   <=  I_SDO               ; 
                    end 
                4'd7:    // 接收第4位
                    begin
                        O_SCLK          <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[4]   <=  I_SDO               ; 
                    end 
                4'd9:    // 接收第3位
                    begin
                       O_SCLK           <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[3]   <= I_SDO                ; 
                    end                            
                4'd11:    // 接收第2位
                    begin
                        O_SCLK          <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[2]   <=  I_SDO               ; 
                    end 
                4'd13:    // 接收第1位
                    begin
                       O_SCLK           <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b0                ;
                        O_data_out[1]   <=  I_SDO               ; 
                    end 
                4'd15:    // 接收第0位
                    begin
                       O_SCLK           <=  1'b1                ;
                        R_rx_state      <=  R_rx_state + 1'b1   ;
                        O_rx_done       <=  1'b1                ;
                        O_data_out[0]   <=  I_SDO               ; 
                    end
                default:R_rx_state  <=  4'd0                    ;   
            endcase 
        end    
    else
        begin
            R_tx_state  <=  4'd0    ;
            R_rx_state  <=  4'd0    ;
            O_tx_done   <=  1'b0    ;
            O_rx_done   <=  1'b0    ;
            O_CS        <=  1'b1    ;
            O_SCLK      <=  1'b0    ;
            O_SDI       <=  1'b0    ;
            O_data_out  <=  8'd0    ;
        end      
end

endmodule

异步FIFO的可以参考这篇文章:
https://blog.csdn.net/alangaixiaoxiao/article/details/81432144

刚入硬件语言,不要着急;
重点不在于写Verilog HDL程序;
在于懂的每个模块的功能和时序;
也就是说,重点在于设计;

无论是Altera还是Xilinx FPGA都可以作为入门的学习,这些工程也都可以使用Testbench,做仿真;

https://blog.csdn.net/sinat_31206523/article/details/104713955)

鄙人博客分栏,希望可以帮忙。
FPGA设计从硬件到软件

如有问题,也可以私信沟通。